我正在使用 customBinding 端点构建 WCF Web 服务,但在接受另一方发送给我的 WS-Security 标头时遇到困难。我们都遵循英国国家卫生服务局制定的规范,因此我无法修改这些要求。
基本结构<wsse:Security>
根据规范,标题应如下所示:
<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>
在我的网络服务中,我尝试使用以下绑定:
<customBinding>
<binding name="wsHttpSoap11" >
<textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
<security authenticationMode="MutualCertificate">
</security>
<httpTransport/>
</binding>
</customBinding>
(我使用 customBinding 的原因是我必须同时支持WS-寻址 and WS-安全 over SOAP 1.1,并听取了建议这个答案 https://stackoverflow.com/a/5418950/483162.)
如果我通过 Fiddler 运行示例请求,我会在 WCF 跟踪中收到以下错误:
找不到令牌验证器
'System.IdentityModel.Tokens.UserNameSecurityToken' 令牌类型。代币
根据当前的安全性,该类型不能被接受
设置。
我相信这是因为它无法验证<UsernameToken>
。如果我将绑定安全性更改为:
<security authenticationMode="UserNameForCertificate">
然后我得到这个错误:
找不到令牌验证器
'System.IdentityModel.Tokens.X509SecurityToken' 令牌类型。代币
根据当前的安全设置,无法接受该类型。
我相信这是因为它现在无法验证<BinarySecurityToken>
!
因此,问题是:
- 我对错误消息原因的假设是否正确
(它在当前配置中只能处理一个令牌)?
- 如何将其配置为接受这两个令牌?
Update
感谢@Yaron,我现在添加了一个自定义绑定扩展,并且用户名安全令牌 and X509安全令牌正在验证。
然而,它现在在验证 XML 签名的阶段失败了。 HTTP响应中返回的异常是:
消息安全验证失败。
如果我深入研究服务跟踪查看器中的堆栈跟踪,我会看到:
System.Security.Cryptography.CryptographicException...
签名验证失败。
在 System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm 哈希,
AsymmetrySignatureDeformatter 去格式器)
在 System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verifyKey)...
谁能帮我弄清楚为什么会发生这种情况?我现在有点迷失了。我尝试使用一些示例代码 http://msdn.microsoft.com/en-us/library/ms229950%28v=vs.90%29.aspx尝试手动验证签名,但它说签名无效。在我返回供应商之前如何确定是否是这样?这是应该起作用的东西吗?我们应该在某个地方共享一些证书吗?