WCF自定义验证器:如何从自定义验证器初始化"用户"对象

cod*_*eim 5 c# wcf wcf-security

我有一个工作自定义UserNamePasswordValidator调用我的Oracle数据库.

此类派生自System.IdentityModel.Selectors.UserNamePasswordValidator,Validate()方法返回void.

我从数据库加载我的User对象,一旦验证了密码,我想隐藏我的"User"对象,以便服务可以在进行业务时访问它.在ASP.NET/Java领域,我会把它存入一个会话,或者我的整个Controller类.如何从WCF中的Validator执行此操作?

或者,换句话说,WCF中为服务设置自定义用户域对象的最佳做法是什么.

更新:这就是我如何解决它.我在验证器期间缓存User对象,然后在AuthorizatinPolicy步骤中访问它.

  // this gets called after the custom authentication step where we loaded the User
  public bool Evaluate(EvaluationContext evaluationContext, ref object state)
  {
     // get the authenticated client identity
     IIdentity client = GetClientIdentity(evaluationContext);

     User user;
     OraclePasswordValidator.users.TryGetValue(client.Name, out user);
     if(user != null) {
        // set the custom principal
        evaluationContext.Properties["Principal"] = user;
        return true;
     }

     return false;
  }
Run Code Online (Sandbox Code Playgroud)

Kje*_*sen 5

我不是WCF专家,但从我到目前为止所阅读和实现的内容来看,"正确"的方法是使用它Validator验证用户,然后实现一个IAuthorizationPolicy来进行实际的授权.因此,在授权策略中,您将在当前线程上设置自定义主体.

为了能够从用户名/密码验证转发信息,您可以实现从中继承的安全性令牌验证器UserNameSecurityTokenAuthenticator.SecurityTokenAuthenticator将首先调用验证器,如果验证成功,它可以添加自定义授权策略并通过构造函数将userinfo发送到策略.这句话有点长:

public class CustomUsernameSecurityTokenAuthenticator : UserNameSecurityTokenAuthenticator
{
    protected override bool CanValidateTokenCore(System.IdentityModel.Tokens.SecurityToken token)
    {
        return (token is UserNameSecurityToken);
    }

    protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateTokenCore(SecurityToken token)
    {
        var authorizationPolicies = new List<IAuthorizationPolicy>();

        try
        {
            var userNameToken = token as UserNameSecurityToken;
            new CustomUserNameValidator().Validate(userNameToken.UserName, userNameToken.Password);

            var claims = new DefaultClaimSet(ClaimSet.System, new Claim(ClaimTypes.Name, userNameToken.UserName, Rights.PossessProperty));

            authorizationPolicies.Add(new CustomAuthorizationPolicy(claims));
        }
        catch (Exception)
        {
            authorizationPolicies.Add(new InvalidAuthorizationPolicy());
            throw;
        }
        return authorizationPolicies.AsReadOnly();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一篇文章描述了涉及的类的更多内容; http://blogs.msdn.com/card/archive/2007/10/04/how-identity-providers-can-show-custom-error-messages-in-cardspace.aspx