在 WCF customBinding 中同时接受 UsernameToken 和 BinarySecurityToken [英] Accepting both UsernameToken and BinarySecurityToken in WCF customBinding

查看:22
本文介绍了在 WCF customBinding 中同时接受 UsernameToken 和 BinarySecurityToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 customBinding 端点构建 WCF Web 服务,但在接受另一方发送给我的 WS-Security 标头时遇到困难.我们都遵循英国国民健康服务署制定的规范,因此我无法修改这些要求.

I am building a WCF web service with a customBinding endpoint and am getting stuck accepting the WS-Security header that is being sent to me by another party. We are both following a specification authored by the UK National Health Service, so I am unable to amend the requirements.

头的基本结构应该如下,根据规范:

The basic structure of the <wsse:Security> header should be as follows, according to the specification:

<wsse:Security>
    <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurityutility-1.0.xsd" wsu:Id="6CCF6A2B-11A6-11DF-86D1-236A99759561" >
        <wsu:Created>2012-06-12T09:00:00Z</wsu:Created>
        <wsu:Expires>2012-06-12T09:15:00Z</wsu:Expires>
    </wsu:Timestamp>
    <wsse:UsernameToken>
        <wsse:Username>SomeUsername</wsse:Username>
    </wsse:UsernameToken>
    <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsssoap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-
200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="30b91ede-35c2-11df-aac9-97f155153931 ">xxx...</wsse:BinarySecurityToken>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#RSA-SHA1" />
            <Reference URI="#6CCF6A2B-11A6-11DF-86D1-236A99759561" />
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>xxx...</DigestValue>
        </SignedInfo>
        <SignatureValue>xxx...</SignatureValue>
        <KeyInfo>
            <wsse:SecurityTokenReference>
                <wsse:Reference URI="#30b91ede-35c2-11df-aac9-97f155153931 "/>
            </wsse:SecurityTokenReference>
        </KeyInfo>
    </Signature>
</wsse:Security>

在我的网络服务中,我尝试使用以下绑定:

In my web service, I have tried using the following binding:

<customBinding>
    <binding name="wsHttpSoap11" >
        <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
        <security authenticationMode="MutualCertificate">
        </security>
        <httpTransport/>
    </binding>
</customBinding>

(我使用 customBinding 的原因是我必须通过 SOAP 1.1 支持 WS-AddressingWS-Security,并且从这个答案中获得建议.)

(The reason I am using customBinding is that I have to support both WS-Addressing and WS-Security over SOAP 1.1, and took advice from this answer.)

如果我通过 Fiddler 运行示例请求,我会在 WCF 跟踪中收到以下错误:

If I run a sample request through Fiddler, I get the following error in my WCF trace:

无法找到令牌验证器'System.IdentityModel.Tokens.UserNameSecurityToken' 令牌类型.代币根据当前的安全性,不能接受这种类型的设置.

Cannot find a token authenticator for the 'System.IdentityModel.Tokens.UserNameSecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.

我相信这是因为它无法验证 .如果我将绑定安全性更改为:

I believe this is because it cannot authenticate the <UsernameToken>. If I change the binding security to:

<security authenticationMode="UserNameForCertificate">

然后我得到这个错误:

无法找到令牌验证器System.IdentityModel.Tokens.X509SecurityToken"令牌类型.代币根据当前的安全设置,无法接受该类型.

Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings.

我相信这是因为它现在无法验证

I believe this is because it now cannot authenticate the <BinarySecurityToken>!

因此,问题是:

  1. 我对错误消息原因的假设是否正确(在当前配置中它只能处理一个令牌)?
  2. 如何配置它以接受两个令牌?

更新

感谢@Yaron,我现在添加了一个自定义绑定扩展,UserNameSecurityTokenX509SecurityToken 都在验证中.

Thanks to @Yaron I have now added a custom binding extension and both the UserNameSecurityToken and X509SecurityToken are validating.

然而,它现在在验证 XML 签名的阶段失败了.HTTP 响应中返回的异常为:

However it is now failing at the stage where it verifies the XML signature. The exception returned in the HTTP response is:

邮件安全验证失败.

如果我在服务跟踪查看器中深入研究堆栈跟踪,我会看到:

If I dig deeper into the stack trace in the service trace viewer, I see:

System.Security.Cryptography.CryptographicException...

System.Security.Cryptography.CryptographicException...

签名验证失败.

在 System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash,AsymmetricSignatureDeformatter deformatter)在 System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verifyKey)...

at System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm hash, AsymmetricSignatureDeformatter deformatter) at System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey)...

谁能帮我弄清楚为什么会这样?我现在有点迷茫.我尝试使用 一些示例代码尝试手动验证签名,但它说签名无效.在我回到供应商那里之前,我如何确定它是否存在?这是应该起作用的东西吗?我们是否应该在某个地方共享一些证书?

Can anyone help me figure out why this is happening? I'm kind of lost at the moment. I tried using some sample code to attempt to manually verify the signature, but it says the signature is not valid. How can I be sure whether it is or not before I go back to the supplier? Is this something that should just work? Should we be sharing some certificates somewhere along the line?

推荐答案

您将需要从代码创建绑定.

you will need to create the binding from code.

        var b = new CustomBinding();
        var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
        sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
        sec.MessageSecurityVersion =
            MessageSecurityVersion.
                WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        sec.IncludeTimestamp = true;
        sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;

        b.Elements.Add(sec);
        b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
        b.Elements.Add(new HttpTransportBindingElement());

(某些值是估计值,因为我无法通过您的帖子判断您使用的是哪个肥皂版本或是否应用了 ssl)

(some of the values are estimated since I cannot tell by your post which soap version you use or if ssl is applied)

另一个您可能会在稍后运行的问题是您需要在 ServiceContract 属性上设置 ProtectionLevel.SignOnly,但这与此问题无关.

another gotcha you may run too later is that you need to have ProtectionLevel.SignOnly on your ServiceContract attributes, but this is not related to this question.

这篇关于在 WCF customBinding 中同时接受 UsernameToken 和 BinarySecurityToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆