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

C# WCF用户名验证:我可以在自定义ServiceAuthorizationManager中获取用户名吗?,c#,.net,wcf,authorization,C#,.net,Wcf,Authorization,我有一个WCF服务正在使用自定义的ServiceAuthorizationManager。自定义身份验证管理器已设置为处理Windows和窗体身份验证 但是,如果我连接的客户端设置为UserNameauth,我似乎在任何地方都找不到用户名 客户端代码如下所示: this.ClientCredentials.UserName.UserName = "user"; this.ClientCredentials.UserName.Password = "pass"; this.Open(); this

我有一个WCF服务正在使用自定义的
ServiceAuthorizationManager
。自定义身份验证管理器已设置为处理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...
    }
}
这可能吗

  • 未设置
    线程.CurrentPrincipal
  • 未设置operationContext.ServiceSecurityContext.PrimaryIdentity
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
    为空
用户/pwd是否应该在任何地方可用?或者我也必须添加一个自定义的
UsernamePasswordValidator


更新:所以我添加了一个自定义的
用户名密码验证器
和一个
IAuthorizationPolicy
。 我更新的WCF配置如下所示:

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

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

“用户名”用户的登录失败。确保用户具有有效的Windows帐户。 位于System.IdentityModel.Selectors.WindowsUserNameSecurityTokenAuthenticator.ValidateUserNamePasswordCore(字符串用户名、字符串密码)
在他们中的任何一个被运行之前。嗯…

这通常在-中处理,这是您唯一可以访问密码的地方。但是,这不是您设置主体的地方-这将在
IAuthorizationPolicy
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;
}
bool IAuthorizationPolicy.Evaluate(
EvaluationContext EvaluationContext,参考对象状态)
{           
IList标识符;
对象识别对象;
if(evaluationContext.Properties.TryGetValue(
“身份”,out identsObject)和&(idents)=
identsObject as IList)!=null)
{
foreach(身份识别中的身份识别)
{
如果(标识)已验证&&
ident.AuthenticationType==TrustedAuthenticationType)
{                           
evaluationContext.Properties[“主体”]
=//我们的校长
返回true;
}
}
}
如果(!evaluationContext.Properties.ContainsKey(“主体”))
{
evaluationContext.Properties[“Principal”]=//TODO anon
}                
返回false;
}
(其中,
TrustedAuthType
是我们的密码验证器的名称)


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

谢谢!对于以后可能需要它的任何人,下面是如何添加自定义授权策略:如果“标识”为空,会出现什么问题?我也有一个“定制”的principalPermissionMode和一个授权策略,就像您在example@Juri-那听起来他们是匿名的。。。除此之外,很难回答。我解决了“身份”问题,这是一个在我的工作站上无法正常工作的问题。然而,我后来遇到的问题是,我必须模拟我的身份,这可能不在自定义授权策略阶段。因此,我采用了我在博客文章中记录的方法(如果有人碰巧遇到同样的问题):请看一下: