我需要创建一个调用 bea webservice 的 WCF 客户端。
我不断从网络服务收到此响应:
无法使用任何受支持的令牌类型验证签名
所以我把注意力转向了客户端<->服务通信的签名部分:
来自网络服务的部分 wsdl:
<s0:Policy s1:Id="Sign.xml">
<wssp:Integrity xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
xmlns:wssp="http://www.bea.com/wls90/security/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<wssp:CanonicalizationAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
<wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SystemHeaders()
</wssp:MessageParts>
</wssp:Target>
<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
<wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part">
wls:SecurityHeader(wsu:Timestamp)
</wssp:MessageParts>
</wssp:Target>
<wssp:Target>
<wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
<wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wssp:MessageParts>
</wssp:Target>
<wssp:SupportedTokens>
<wssp:SecurityToken
IncludeInMessage="true"
TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
<wssp:TokenIssuer>REMOVED</wssp:TokenIssuer>
</wssp:SecurityToken>
</wssp:SupportedTokens>
</wssp:Integrity>
<wssp:MessageAge Age="60" xmlns:wssp="http://www.bea.com/wls90/security/policy"/>
从 wsdl 我了解到我必须签名:
- SystemHeaders(我真正的问题)
- 时间戳(做了那个)
- 正文(做到了,并且还对其进行了加密)
我有生产这种肥皂的工作代码(使用 microsoft.web.services3):
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#Timestamp-fc23bf88-381b-4f2b-b992-ff07b41b5c38"> <!--This is the timestamp-->
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>Removed</DigestValue>
</Reference>
<Reference URI="#Id-4b4f1377-eac0-4db0-b334-384d7b14e286"> <!--This is the encrypted body-->
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>Removed</DigestValue>
</Reference>
<Reference URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117"> <!--This is the SecurityTokenReference:Reference-->
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>Removed</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Removed</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference
URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="Id-4b4f1377-eac0-4db0-b334-384d7b14e286">
<xenc:EncryptedData
Id="Enc-8b5b4ef4-1c12-409b-8159-dec2889a8fa8"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<xenc:CipherData>
<xenc:CipherValue>Removed<xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
我已承诺使用 WCF 完成这项工作,因此 microsoft.web.services3 不是一个选项。对不起。
我已经使用 svcutil 创建了代理。没有汗水。我手动对代理所做的唯一更改是我已附加
, ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign
到 System.ServiceModel.ServiceContractAttribute
我当前的代码产生这个标志部分:
<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="#_1"> <!--This is the body-->
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Removed</DigestValue>
</Reference>
<Reference URI="#uuid-e7f22d2b-5a91-421a-aced-df7ab8a92f8d-1"> <!--This is the timestamp-->
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Removed</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Removed</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:Reference
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
URI="#uuid-3b0e28b3-d47f-4eb2-ab0a-77f94dd76af0-2"/>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body u:Id="_1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<e:EncryptedData
Id="_2"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
<e:CipherData><e:CipherValue>Removed</e:CipherValue></e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>
从我的 app.config:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="testBinding">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
</textMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false"
authenticationScheme="Anonymous" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true"
maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered"
unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://url.com/testservice/testservicePort" binding="customBinding"
bindingConfiguration="testBinding"
contract="testservicePortType"
name="testservicePort"/>
</client>
</system.serviceModel>
我在这样的代码中配置 CustomBinding:
private static CustomBinding CreateCustomBinding()
{
var customBinding = new CustomBinding();
SecurityBindingElement securityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement(
MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
AsymmetricSecurityBindingElement asymmetricSecurityBindingElement =
(AsymmetricSecurityBindingElement)securityBindingElement;
asymmetricSecurityBindingElement.SetKeyDerivation(false);
asymmetricSecurityBindingElement.EnableUnsecuredResponse = true;
asymmetricSecurityBindingElement.AllowInsecureTransport = true;
asymmetricSecurityBindingElement.AllowSerializedSigningTokenOnReply = true;
asymmetricSecurityBindingElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;
asymmetricSecurityBindingElement.IncludeTimestamp = true;
asymmetricSecurityBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
asymmetricSecurityBindingElement.RequireSignatureConfirmation = false;
asymmetricSecurityBindingElement.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;
customBinding.Elements.Clear();
customBinding.Elements.Add(asymmetricSecurityBindingElement);
customBinding.Elements.Add(new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11,
AddressingVersion.None),
WriteEncoding = new System.Text.UTF8Encoding()
});
HttpTransportBindingElement httpbinding = new HttpTransportBindingElement();
httpbinding.AuthenticationScheme = AuthenticationSchemes.Anonymous;
httpbinding.MaxReceivedMessageSize = 1024 * 1024;
customBinding.Elements.Add(httpbinding);
return customBinding;
}
我试图了解 microsoft.web.services3 代码中发生了什么(我还没有写过),似乎作者完全重写了 securityheader。这似乎不是最好的解决方案(但也许是唯一的?)
有人可以帮我吗?