【问题标题】:WCF UserName Authentication: Can I get the Username in a custom ServiceAuthorizationManager?WCF 用户名身份验证:我可以在自定义 ServiceAuthorizationManager 中获取用户名吗?
【发布时间】:2013-01-13 10:49:25
【问题描述】:

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

但是,如果我与设置为 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


更新:所以我添加了一个自定义 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>

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

在它们中的任何一个运行之前。嗯……

【问题讨论】:

    标签: c# .net wcf authorization


    【解决方案1】:

    这通常在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;
    }
    

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

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

    【讨论】:

    • 谢谢!对于以后可能需要它的任何人,这里是添加自定义 AuthorizationPolicy 的方法:msdn.microsoft.com/en-us/library/ms729794.aspx
    • 如果“身份”为空会出现什么问题?我也有一个“自定义” principalPermissionMode 和一个 AuthorizationPolicy 就像你在你的例子中一样
    • @Juri - 听起来他们是匿名的……除此之外,很难回答。
    • 我解决了“身份”问题,这是一个在我的工作站本地无法正常工作的问题。但是,后来我遇到的问题是我必须冒充我的身份,这不可能在自定义授权策略的阶段。因此,我采用了我在博客文章中记录的这种方法(如果有人碰巧遇到同样的问题):blog.js-development.com/2010/11/…
    猜你喜欢
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    相关资源
    最近更新 更多