我正在尝试在过去4天内使用.net和WCF编写一个soap客户端来连接具有特定安全要求的Web服务。
soap消息需要对Timestamp,Message和BinarySecurityToken签名(未加密),请求通过https连接发送,并使用soap 1.1。
使用soapui证明这是可能的,并且生成的原始消息如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://somewebservice.com/someoperation/v1" xmlns:v11="http://somewebservice.com/someoperation/types/v1">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:BinarySecurityToken
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-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="X509-65E1C83C68B360A6311522317037930116">binarydata...</wsse:BinarySecurityToken>
<ds:Signature Id="SIG-65E1C83C68B360A6311522317037936120" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="soapenv v1 v11" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#TS-65E1C83C68B360A6311522317037928115">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="wsse soapenv v1 v11" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>/b2PmmLNJ+CdlMA0NGiD3SNMT5c=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#id-65E1C83C68B360A6311522317037930119">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="v1 v11" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>+rIhQ2RiZNYKWU75lvUDsgGS4Ow=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#X509-65E1C83C68B360A6311522317037930116">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>cn9f/Yn3Eer5h43znGZvSDfA8xE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
binarydata...
</ds:SignatureValue>
<ds:KeyInfo Id="KI-65E1C83C68B360A6311522317037930117">
<wsse:SecurityTokenReference wsu:Id="STR-65E1C83C68B360A6311522317037930118">
<wsse:Reference URI="#X509-65E1C83C68B360A6311522317037930116" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-65E1C83C68B360A6311522317037928115">
<wsu:Created>2018-03-29T09:50:37Z</wsu:Created>
<wsu:Expires>2018-03-29T09:51:37Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body wsu:Id="id-65E1C83C68B360A6311522317037930119" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<v1:HasAnEboxRequest>
<v11:QualityCode>ENTERPRISE</v11:QualityCode>
<v11:EboxID>
<v11:CompanyID>0474773230</v11:CompanyID>
</v11:EboxID>
</v1:HasAnEboxRequest>
</soapenv:Body>
</soapenv:Envelope>
这里的关键是我认为SignedInfo标签之间的三个块。 (他们引用Timestamp,Message和BinarySecurityToken)
我尝试了很多东西,但我只能得到一条只有时间戳签名的消息,如下所示:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2018-03-29T19:17:32.420Z</u:Created>
<u:Expires>2018-03-29T19:22:32.420Z</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="uuid-ae79fbee-ea5f-4ebb-b461-c141cd743bb7-1"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">binarydata...</o: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="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>7WbZ1cY3CS4hKk7Pb6+wpFUQi8k=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>binarydata...</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-ae79fbee-ea5f-4ebb-b461-c141cd743bb7-1"/>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<HasAnEboxRequest xmlns="http://somewebservice.com/someoperation/v1">
<QualityCode xmlns="http://somewebservice.com/someoperation/types/v1">QUAL_EMP_NOSS</QualityCode>
<EboxID xmlns="http://somewebservice.com/someoperation/types/v1">
<CompanyID>0474773230</CompanyID>
</EboxID>
</HasAnEboxRequest>
</s:Body>
</s:Envelope>
目前我有以下app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="defaultBasicHttpBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<!-- specifies the endpoint to use when calling the service -->
<endpoint address="https://someurl/someendpoint/v1"
binding="basicHttpBinding"
bindingConfiguration="defaultBasicHttpBinding"
behaviorConfiguration="enableCallbackDebug"
contract="ServiceReference1.EboxMessagePortType" name="MyBindingConfig">
<identity>
<dns value="aod:trusto:acc:ebox:publication"/>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="enableCallbackDebug">
<clientCredentials>
<clientCertificate findValue="somecertsubjectname"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"
/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
在代码中,我使用的是由wsdl生成的代理类。
如果有人对解决方案有所了解,那就太棒了。
另外,我想也许wcf不是这种情况的最佳方式,所以欢迎任何建议。
谢谢!
答案 0 :(得分:0)
也许对别人有所帮助,
我最终没有使用wcf,而是使用模板xml并使用SignedXml(System.Security.Cryptography.Xml)签署不同的部分