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

时间:2009-02-09 19:20:43

标签: c# .net wcf authorization

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

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

客户端代码如下所示:

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

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

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

这可能吗?

  • 未设置Thread.CurrentPrincipal
  • operationContext.ServiceSecurityContext.PrimaryIdentity未设置。
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets为空。

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


更新:我添加了自定义UserNamePasswordValidatorIAuthorizationPolicy。 我更新的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>

如果我在所有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)

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

1 个答案:

答案 0 :(得分:6)

这通常在UsernamePasswordValidator处理 - 这是您唯一可以访问密码的地方。但是,这不是您设置主体的位置 - 这将在IAuthorizationPolicy的{​​{1}}方法中,这可能类似于:

Evaluate

(其中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; } 是我们的密码验证器的名称)

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