可能有WCF STS的用户名/密码和客户端证书?

时间:2011-05-24 14:10:55

标签: wcf authentication certificate wif

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

我们在客户的网站上安装客户。 我希望每个客户都能为自己的客户使用自己的证书。原因是没有“客户站点”验证可能。我可以停用某些用户帐户,但我无法立即禁用客户安装的所有客户端 如果每个客户都有不同的证书,我可以撤销证书,该客户的任何客户都不能再连接。

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

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

干杯。

1 个答案:

答案 0 :(得分:2)

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

在自定义绑定元素中,您需要创建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 the Credentials property类的ClientBase proxy上的属性来执行此操作。您可以做的另一件事是通过端点行为设置客户端证书,如下所示:

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

通过这种方式,您只需要在运行时明确设置用户名/密码。

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