WCF用户名的身份验证:我可以得到用户名和自定义ServiceAuthorizationManager? [英] WCF UserName Authentication: Can I get the Username in a custom ServiceAuthorizationManager?

查看:500
本文介绍了WCF用户名的身份验证:我可以得到用户名和自定义ServiceAuthorizationManager?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用自定义的 ServiceAuthorizationManager WCF服务。自定义身份验证管理器已成立处理Windows和Forms身份验证。

I have a WCF service that is using a custom ServiceAuthorizationManager. The custom auth manager is already set up to handle Windows and Forms authentication.

不过,如果我连接与设置为用户名身份验证客户端,我似乎无法找到任何地方的用户名。

However, if I connect with a client that is set to UserName auth, I can't seem to find the username anywhere.

客户端code是这样的:

The client code looks like this:

this.ClientCredentials.UserName.UserName = "user";
this.ClientCredentials.UserName.Password = "pass";
this.Open();
this.MyMethod(); // my actual contract method
this.Close();

然后在服务器上,我有我的自定义身份验证管理器:

Then on the server, I have my custom auth manager:

public sealed class AppAuthorizationManager : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext, ref Message message)
    {
        // would like to check user/pwd here...
    }
}

这可能吗?

Is this possible?

  • Thread.CurrentPrincipal中没有设置,
  • operationContext.ServiceSecurityContext.PrimaryIdentity 未设置。
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets 是空的。
  • The Thread.CurrentPrincipal is not set,
  • operationContext.ServiceSecurityContext.PrimaryIdentity is not set.
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets is empty.

时的用户名/密码应该在任何地方可用?还是我必须添加自定义 UsernamePasswordValidator 吗?

Is the user/pwd supposed to be available anywhere? Or do I have to add a custom UsernamePasswordValidator too?

更新:所以我增加了一个自定义的 UserNamePasswordValidator IAuthorizationPolicy 。 我的更新WCF的配置是这样的:

Update: So I added a custom UserNamePasswordValidator and an IAuthorizationPolicy. My updated WCF config looks like this:

<behavior name="Server2ServerBehavior">
  <serviceMetadata httpGetEnabled="true" />
  <serviceDebug includeExceptionDetailInFaults="true" />
  <serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="MyApp.AuthManager, MyApp">
    <authorizationPolicies>
      <add policyType="MyApp.TokenAuthorizationPolicy, MyApp" />
    </authorizationPolicies>
  </serviceAuthorization>
  <serviceCredentials>
    <userNameAuthentication customUserNamePasswordValidatorType="MyApp.PFUserNameValidator, MyApp" />
  </serviceCredentials>
</behavior>

如果我把所有3这些类的断点,WCF抛出异常:

If I set a breakpoint in all 3 of those classes, WCF throws the exception:

LogonUser failed for the 'username' user. Ensure that the user has a valid Windows account.
   at System.IdentityModel.Selectors.WindowsUserNameSecurityTokenAuthenticator.ValidateUserNamePasswordCore(String userName, String password)

在其中任何一个都运行。嗯...

Before any of them are run. Hmmm...

推荐答案

这是在的 UsernamePasswordValidator - 这是你将有机会获得密码的唯一的地方。然而,这是不是你设置的委托 - 这将是在 IAuthorizationPolicy 评估方法,该方法看起来是这样的:

This is normally handled in the UsernamePasswordValidator - which is the only place you'll have access to the password. However, this isn't where you set the principal - that would be in the IAuthorizationPolicy's Evaluate method, which might look something like:

bool IAuthorizationPolicy.Evaluate(
    EvaluationContext evaluationContext, ref object state)
{           
    IList<IIdentity> idents;
    object identsObject;
    if (evaluationContext.Properties.TryGetValue(
        "Identities", out identsObject) && (idents =
        identsObject as IList<IIdentity>) != null)
    {
        foreach (IIdentity ident in idents)
        {
            if (ident.IsAuthenticated &&
                ident.AuthenticationType == TrustedAuthType)
            {                           
                evaluationContext.Properties["Principal"]
                    = //TODO our principal
                return true;
            }
        }
    }
    if (!evaluationContext.Properties.ContainsKey("Principal"))
    {
        evaluationContext.Properties["Principal"] = //TODO anon
    }                
    return false;
}

(其中 TrustedAuthType 是我们的密码验证程序的名称)

(where TrustedAuthType is the name of our password validator)

有了这个地方,线程的校长将被设置,我们可以找出我们自己(和使用基于角色的安全性等)

With this in place, the thread's principal will be set, and we can identify ourselves (and use roles-based security etc)

这篇关于WCF用户名的身份验证:我可以得到用户名和自定义ServiceAuthorizationManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆