【问题标题】:WCF - Get password from MessageHeaderWCF - 从 MessageHeader 获取密码
【发布时间】:2011-09-14 10:15:19
【问题描述】:

我有一个安全模式设置为消息的 WCF 服务。我使用自定义 UserNamePasswordValidator 的用户名作为客户端凭据类型。

 NetTcpBinding binding = new NetTcpBinding(SecurityMode.Message, false);
 binding.Security.Mode = SecurityMode.Message;
 binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

用户通过身份验证后,我可以在服务器端检索密码吗? 密码是否保存在请求的 MessageHeader 中?我可以从 MessageHeader 中获取它(用户通过身份验证后)吗?

安吉拉

【问题讨论】:

    标签: wcf security


    【解决方案1】:

    据我了解您的问题,您有一个 WCF 服务,该服务需要用户名和密码进行身份验证。为此,您已配置自定义 UserNamePasswordValidator,而不是依赖 WCF (= Windows) 采用的默认机制。

    在此处查看有关如何在 WCF 中设置自定义用户名和密码验证器的更多信息:

    http://msdn.microsoft.com/en-us/library/aa702565.aspx

    我假设您已经创建了一个派生自 UserNamePasswordValidator 类型的类。您的自定义类型负责根据包含您的用户列表的存储(数据库、xml 文件...等)检查用户名和密码。验证器必须确定它是否在与有效用户打交道。如果是这样,它可以对用户进行身份验证。

    例如:

    public class CustomUserNameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (null == userName || null == password)
            {
                throw new ArgumentNullException();
            }
    
            // Validator username and password here
            // bool isValid = ...;
    
            if (!isValid)
            {
                throw new SecurityTokenException("Access denied.");
            }
        }
    }
    

    如您所见,如果您正确实现了自定义 UserNamePasswordValidator,您已经有一个地方可以访问客户端提交的用户名和密码。

    如果您想在用户通过身份验证后访问用户名,例如在服务方法之一的主体中,您可以使用以下内容:

    var userName = 
        OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
    

    查看ServiceSecurityContext type 了解更多信息。

    如果你也想让密码可用,那么我建议你看看下面的文章:

    http://www.neovolve.com/post/2008/04/07/wcf-security-getting-the-password-of-the-user.aspx

    我猜你也可以从当前 OperationContext 中提取用户名和密码,正如前面提到的文章中的一个 cmet 所建议的那样。

    public void MyServiceMethod()
    {
        var context = OperationContext.Current;
        var token = context.IncomingMessageProperties.Security
                           .IncomingSupportingTokens[0].SecurityToken as  
                    System.IdentityModel.Tokens.UserNameSecurityToken; 
        //...
    }
    

    【讨论】:

    • 嗨,这是正确的我有我的自定义 UserNamePasswordValidator,但我想在用户通过身份验证后检索密码,例如在调用我的服务方法时在服务端。
    • 是的,我已经根据上述站点的示例实现了一个解决方案。问题是它是否存在更简单的解决方案。其中一个 cmets 提到使用 UserNameSecurityToken securityToken = OperationContext.Current.IncomingMessageProperties.Security.IncomingSupportingTokens[0].SecurityToken as UserNameSecurityToken;
    • 我很抱歉,但这从来都不是问题。您最初的问题是如何在使用自定义 UserNamePasswordValidator 时检索用户名和密码。不要为您从未提及的可能解决方案找到更简单的替代方案。
    • 那个“提取”不起作用,至少不是在所有情况下(不是在我的情况下)。那里只有一个令牌,它不是 UserNameSecurity 一个(进入调试器以获取真实类型)。
    猜你喜欢
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多