WCF UserName身份验证:我可以在自定义ServiceAuthorizationManager中获取用户名吗?

Cod*_*ike 4 .net c# wcf authorization

我有一个使用自定义的WCF服务ServiceAuthorizationManager.自定义身份验证管理器已设置为处理Windows和Forms身份验证.

但是,如果我连接到设置为UserNameauth 的客户端,我似乎无法在任何地方找到用户名.

客户端代码如下所示:

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

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

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

这可能吗?

  • Thread.CurrentPrincipal未设置,
  • operationContext.ServiceSecurityContext.PrimaryIdentity 没有设定.
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets 是空的.

用户/密码应该在任何地方可用吗?或者我是否还要添加自定义UsernamePasswordValidator


更新:所以我添加了一个自定义UserNamePasswordValidator和一个IAuthorizationPolicy.我更新的WCF配置如下所示:

<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>
Run Code Online (Sandbox Code Playgroud)

如果我在所有3个类中设置断点,WCF会抛出异常:

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)
Run Code Online (Sandbox Code Playgroud)

在任何一个运行之前.嗯...

Mar*_*ell 6

这通常在UsernamePasswordValidator中处理- 这是您唯一可以访问密码的地方.然而,这是不是你设置的委托-这将是在IAuthorizationPolicyEvaluate方法,它可能看起来是这样的:

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;
}
Run Code Online (Sandbox Code Playgroud)

(TrustedAuthType密码验证器的名称在哪里)

有了这个,线程的主体将被设置,我们可以识别自己(并使用基于角色的安全性等)

  • 我解决了"身份"问题,这是我工作站本地无法正常工作的问题.然而,之后我遇到的问题是我不得不冒充我的身份,这可能不是在自定义授权政策阶段.因此,我采用了我在博客文章中记录的这种方法(如果有人碰巧遇到同样的问题):http://blog.js-development.com/2010/11/intercepting-wcf-operation-calls-with.html (2认同)