WCF自定义验证:如何初始化"用户"从自定义的验证对象 [英] WCF Custom Validator: How to initialize a "User" object from custom validator

查看:97
本文介绍了WCF自定义验证:如何初始化"用户"从自定义的验证对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用到我的Oracle数据库工作自UserNamePasswordValidator。



本类从System.IdentityModel.Selectors.UserNamePasswordValidator和validate()方法返回void派生



我从数据库加载我的用户对象,一旦密码验证,我想藏匿我的用户对象,以便将有关服务时可以访问它其业务。在ASP.NET / Java的土地我会藏入一个会话,或者我的整体Controller类。我该怎么做这在WCF的验证?



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



更新:这是我如何围绕它的工作。我缓存验证过程中的用户对象,然后再访问它在AuthorizatinPolicy一步。

  //这被定制之后调用认证步骤,我们安装在用户
公共BOOL评估(evaluationContext evaluationContext,参考对象的状态)
{
//得到验证的客户端身份
的IIdentity客户端= GetClientIdentity(evaluationContext);

的用户的用户;
OraclePasswordValidator.users.TryGetValue(client.Name,出用户);
如果(!用户= NULL){
//设置自定义主体
evaluationContext.Properties [校长] =用户;
返回真;
}

返回FALSE;
}


解决方案

我不是一个WCF专家,但是从我读过,到目前为止实施的正确的方式做,这将是使用验证身份验证用户,然后实施 IAuthorizationPolicy 做实际的授权。因此,这将是你会设置在当前线程上的自定义主体的授权策略。



要能够从用户名/密码验证转发信息,可以实现一个安全令牌认证,从 UserNameSecurityTokenAuthenticator 继承。该SecurityTokenAuthenticator会先调用验证,如果验证成功,它可以添加自定义的授权策略,并发送用户信息,通过构造函数的政策。东西长此行:

 公共类CustomUsernameSecurityTokenAuthenticator:UserNameSecurityTokenAuthenticator 
{
保护覆盖布尔CanValidateTokenCore (System.IdentityModel.Tokens.SecurityToken令牌)
{
回报率(令牌UserNameSecurityToken);
}

保护覆盖ReadOnlyCollection还< IAuthorizationPolicy> ValidateTokenCore(SecurityToken令牌)
{
变种authorizationPolicies =新的List< IAuthorizationPolicy>();


{
VAR用户名令牌=令牌作为UserNameSecurityToken;
新CustomUserNameValidator()验证(userNameToken.UserName,userNameToken.Password);

变种索赔=新DefaultClaimSet(ClaimSet.System,新的索赔(ClaimTypes.Name,userNameToken.UserName,Rights.PossessProperty));

authorizationPolicies.Add(新CustomAuthorizationPolicy(索赔));
}
赶上(例外)
{
authorizationPolicies.Add(新InvalidAuthorizationPolicy());
抛出;
}
返回authorizationPolicies.AsReadOnly();
}
}



这里有一个描述多一点周围的一篇文章参与班;的 http://blogs.msdn.com/card/archive/2007/10/04/how-identity-providers-can-show-custom-error-messages-in-cardspace.aspx


I have a working custom UserNamePasswordValidator that calls into my Oracle DB.

This class derives from System.IdentityModel.Selectors.UserNamePasswordValidator and the Validate() method returns void.

I load my User object from the database, and once the password is validated, I want to stash my "User" object so the service can access it when going about its business. In ASP.NET / Java land I would stash it into a session, or perhaps my overall Controller class. How do I do this from the Validator in WCF?

Or, in other words, what is the best practice in WCF land to set a custom User domain object for the service.

Update: This is how I've worked around it. I cache the User object during the validator, then access it later in the AuthorizatinPolicy step.

  // 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;
  }

解决方案

I'm not a WCF expert, but from what I've read and implemented so far, the 'correct' way to do this would be to use the Validator to authenticate the user, and then implement an IAuthorizationPolicy to do the actual authorization. So it would be in the authorization policy that you'll set your custom principal on the current thread.

To be able to forward information from the username/password validation, you can implement a security token authenticator that inherits from UserNameSecurityTokenAuthenticator. The SecurityTokenAuthenticator will first call the validator and if validation succeeds, it can add your custom authorization policy and send userinfo to the policy through the constructor. Something a long the lines of this:

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();
    }
}

There's an article here that describes a bit more around the involved classes; http://blogs.msdn.com/card/archive/2007/10/04/how-identity-providers-can-show-custom-error-messages-in-cardspace.aspx

这篇关于WCF自定义验证:如何初始化&QUOT;用户&QUOT;从自定义的验证对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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