我需要创建一个调用bea webservice的WCF客户端。
我一直从网络服务得到这个回复:
无法使用任何支持的令牌类型验证签名
所以我把注意力转向客户端< - >服务通信的签名部分:
来自webservice的部分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我明白我必须签名:
我有生产这种肥皂的工作代码(使用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。这似乎不是最好的解决方案(但可能是唯一的?)
谁能帮助我?
终于想通了:-)
用过这篇文章:
在我写上面的问题之前已经阅读了几次(因此标题非常相似),并且真的不明白为什么它应该起作用。但确实如此!
我的自定义绑定现在看起来像这样:
System.ServiceModel.Channels.AsymmetricSecurityBindingElement
asymmetricSecurityBindingElement = new AsymmetricSecurityBindingElement();
asymmetricSecurityBindingElement.MessageSecurityVersion =
MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
asymmetricSecurityBindingElement.InitiatorTokenParameters = new
System.ServiceModel.Security.Tokens.X509SecurityTokenParameters
{ InclusionMode = SecurityTokenInclusionMode.Never };
asymmetricSecurityBindingElement.RecipientTokenParameters = new
System.ServiceModel.Security.Tokens.X509SecurityTokenParameters
{ InclusionMode = SecurityTokenInclusionMode.Never };
asymmetricSecurityBindingElement.MessageProtectionOrder =
System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
asymmetricSecurityBindingElement.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;
asymmetricSecurityBindingElement.EnableUnsecuredResponse = true;
asymmetricSecurityBindingElement.IncludeTimestamp = true;
asymmetricSecurityBindingElement.SetKeyDerivation(false);
asymmetricSecurityBindingElement.DefaultAlgorithmSuite =
System.ServiceModel.Security.SecurityAlgorithmSuite.TripleDesRsa15;
asymmetricSecurityBindingElement.EndpointSupportingTokenParameters.Signed.Add(
new X509SecurityTokenParameters());
customBinding.Elements.Clear();
customBinding.Elements.Add(asymmetricSecurityBindingElement);