我正在用一个customBinding端点构建一个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>在我的web服务中,我尝试使用以下绑定:
<customBinding>
<binding name="wsHttpSoap11" >
<textMessageEncoding messageVersion="Soap11WSAddressingAugust2004" />
<security authenticationMode="MutualCertificate">
</security>
<httpTransport/>
</binding>
</customBinding>(我之所以使用customBinding,是因为我必须同时支持WS--寻址和WS--基于SOAP 1.1的安全,并听取了这个答案的建议。)
如果我通过Fiddler运行一个示例请求,我将在WCF跟踪中得到以下错误:
无法找到'System.IdentityModel.Tokens.UserNameSecurityToken‘令牌类型的令牌身份验证器。根据当前的安全设置,不能接受该类型的令牌。
我相信这是因为它不能验证<UsernameToken>。如果我将绑定安全性更改为:
<security authenticationMode="UserNameForCertificate">然后我得到了这个错误:
无法找到'System.IdentityModel.Tokens.X509SecurityToken‘令牌类型的令牌身份验证器。根据当前的安全设置,不能接受该类型的令牌。
我相信这是因为它现在不能验证<BinarySecurityToken>!
因此,问题是:
更新
多亏了@Yaron,我现在添加了一个自定义绑定扩展,并且UserNameSecurityToken和X509SecurityToken都是有效的。
但是,它现在在验证XML签名的阶段失败了。HTTP响应中返回的异常是:
消息安全验证失败。
如果我在服务跟踪查看器中深入挖掘堆栈跟踪,我会看到:
System.Security.Cryptography.CryptographicException... 签名验证失败。 在System.IdentityModel.SignedXml.VerifySignature(HashAlgorithm散列,AsymmetricSignatureDeformatter变形程序)在System.IdentityModel.SignedXml.StartSignatureVerification(SecurityKey verificationKey).
有人能帮我弄清楚为什么会发生这种事吗?我现在有点不知所措。我尝试使用一些示例代码来手动验证签名,但是它说签名无效。在我回到供货商之前,我怎样才能确定它是否是?这是不是应该奏效的东西?我们是否应该在这条线路上共享一些证书?
发布于 2012-06-12 17:19:39
您需要从代码中创建绑定。
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());(其中一些值是估计的,因为我无法通过您的帖子来判断您使用的是哪个soap版本,或者是否应用了ssl )
另一个您可能运行得太晚的问题是,您需要在您的ProtectionLevel.SignOnly属性上使用ServiceContract,但这与这个问题无关。
https://stackoverflow.com/questions/10999924
复制相似问题