【问题标题】:Possible to have WCF STS with username/password and client certificate?可能有带有用户名/密码和客户端证书的 WCF STS?
【发布时间】:2011-08-31 23:45:53
【问题描述】:

我将 WIF 与 STS 结合使用。一切正常,客户端通过在凭据中发送用户名/密码进行身份验证。

我们在客户的站点安装客户端。 我希望每个客户为其客户使用自己的证书。原因是不可能进行“客户站点”验证。我可以停用一些用户帐户,但我不能一次禁用客户安装的所有客户端。
如果每个客户都有不同的证书,我可以吊销该证书,并且该客户的任何客户都无法再连接。

我找不到任何方法来强制客户端将其证书设置为通信。通常,当身份验证模式设置为 certificate 时这是自动的,但我需要将其设置为 windows 才能发送身份验证。

有没有人知道如何实现这一目标?或者让我知道这是否不可能。

干杯。

【问题讨论】:

    标签: wcf authentication certificate wif


    【解决方案1】:

    当然,您只需要做一些小动作就可以开始使用自定义安全绑定扩展元素来描述令牌以及应该使用哪个令牌进行签名/背书。出于解释的目的,我假设您总是希望证书和用户名/密码都通过。

    在自定义绑定元素中,您需要创建一个TransportSecurityBindingElement 并向其添加令牌参数。可以向三个集合添加令牌参数:SignedEncryptedSignedEndorsing。对于我们在这里讨论的场景,我建议将UserNameSecurityTokenParameters 添加到SignedEncrypted 集合,将X509SSecurityTokenParameters 添加到Endorsing 集合。这意味着消息的有效性/完整性由证书令牌而不是用户名/密码提供,并且用户名/密码令牌将由证书令牌签署加密。这将如下所示:

    public class MySecurityBindingElement : BindingElementExtensionElement
    {
        public override void ApplyConfiguration(BindingElement bindingElement)
        {
            base.ApplyConfiguration(bindingElement);
    
            TransportSecurityBindingElement transportSecurityBindingElement = (TransportSecurityBindingElement)bindingElement;
    
            transportSecurityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(new UserNameSecurityTokenParameters());
    
            transportSecurityBindingElement.EndpointSupportingTokenParameters.Endorsing.Add(new X509SecurityTokenParameters
            {
                InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient,
                ReferenceStyle = SecurityTokenReferenceStyle.Internal,
                RequireDerivedKeys = false,
                X509ReferenceStyle = X509KeyIdentifierClauseType.Any
            });         
        }
    
        protected override BindingElement CreateBindingElement()
        {
            TransportSecurityBindingElement result = new TransportSecurityBindingElement
            {
                IncludeTimestamp = true,
                LocalClientSettings.DetectReplays = false,
                LocalServiceSettings.DetectReplays = false
            };
    
            this.ApplyConfiguration(result);
    
            return result;
         }
    }
    

    然后,从客户端的角度来看,您只需确保为用于与服务器通信的每个通道设置证书和用户名密码。您可以在运行时通过在ChannelFactory 或标准WCF ClientBase proxy 类的the Credentials property 上设置属性来执行此操作。您可以做的另一件事是通过如下端点行为设置客户端证书:

    <endpointBehavior>
        <behavior name="MyBehavior">
            <clientCredentials>
                <clientCertificate findValue="MySubject" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
            </clientCredentials>
        </behavior>
    </endpointBehavior>
    

    这样做,您只需要在运行时明确设置用户名/密码。

    最后,在 STS,您可以通过OperationContext::SupportingTokens 属性读取用户指定的令牌。您会在集合中找到 UserNameSecurityTokenX509SecurityToken 的实例,然后您可以使用这些实例对调用者进行身份验证。

    【讨论】:

    • 感谢您的快速回答!我没想过使用自定义安全绑定。那我明天试试。我希望有一种“内置”的方式来做到这一点。
    • 没有开箱即用的东西,但至少旋钮和开关在那里。 ;)
    • 所以这适用于自定义 STS 还是可以通过 ADFS v2.0 完成?
    • ADFS 2.0 的“令牌发行”部分是 STS 实现。也就是说,这实际上与向特定 STS 发送令牌没有任何关系。您可以使用相同的绑定发送多个安全令牌以及任何请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2013-07-14
    • 2016-03-09
    • 1970-01-01
    相关资源
    最近更新 更多