在 WCF 中操作肥皂信封
Manipulating soap evelope in WCF
对于一个项目,我们正在从荷兰连接到 KVK Handelsregister 数据服务。我们已经设置了一个 WCF 客户端代理 class,但是我们的 soap 信封仍然与他们要求的信封不同,任何解决这 3 个问题的想法:
- 删除 mustUnderstandAttribute
- body元素中没有命名空间(ns:)
- header也没有对OASIS的引用
我们的信封:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://es.kvk.nl/genereerProduct</a:Action>
<a:MessageID>urn:uuid:173035b3-714d-46ef-96c2-1d46962ec897</a:MessageID>
<ActivityId CorrelationId="3d2fb1c7-99db-4c88-9745-6cd187281fc6" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">5f48b058-21d5-46c4-8a8b-02f60556ef0e</ActivityId>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://es.kvk.nl/KVK-DataserviceCT/2012/10</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<genereerProduct xmlns="http://schemas.kvk.nl/schemas/hrip/generiekproduct/2013/01">
<productRequest>
<klantreferentie>QW43BA12</klantreferentie>
<productnaam>Inschrijving</productnaam>
<productsleutel>
<kvkNummer>01048900</kvkNummer>
</productsleutel>
</productRequest>
</genereerProduct>
</s:Body>
</s:Envelope>
应有的信封
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:ns="http://schemas.kvk.nl/schemas/hrip/generiekproduct/2013/01"
xmlns:add="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<add:Action>http://es.kvk.nl/genereerProduct</add:Action>
<add:MessageID>uuid://94-b0e0-d4313c898af0</add:MessageID>
<add:To>http://es.kvk.nl/KVK-DataserviceCT/2012/10</add:To>
</soapenv:Header>
<soapenv:Body>
<ns:genereerProduct>
<ns:productRequest>
<ns:klantreferentie>QW43BA12</ns:klantreferentie>
<ns:productnaam>Inschrijving</ns:productnaam>
<ns:productsleutel>
<ns:kvkNummer>01048900</ns:kvkNummer>
</ns:productsleutel>
</ns:productRequest>
</ns:genereerProduct>
</soapenv:Body>
</soapenv:Envelope>*
按照下面评论中的要求,wsHttpBinding 和 customBinding 的绑定配置。更改此设置对 soap 信封没有影响,自定义绑定的错误是:
ERROR An error occurred while receiving the HTTP response to
https://webservices
8.kvk.nl/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context
being aborted by the server (possibly due to the service shutting
down). See server logs for more de tails.
<bindings>
<wsHttpBinding>
<binding name="ProductServiceSoap11">
<security mode="Transport">
<message clientCredentialType="Certificate"/>
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
<customBinding>
<binding name="WsHttpSoap11" >
<transactionFlow />
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
至少我找到了正确的配置并让这个 link 工作。毕竟摆弄 SOAP 信封只是此连接的整个解决方案的一部分。
但我会添加一些信息,这对我的工作有很大帮助。
1) 日志记录,将其添加到您的配置文件中以启动日志记录
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information,ActivityTracing"
propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="c:\TestKVKService\TestKVKService\bin\Debug\Log\Tracesmore.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="xml" />
</sharedListeners>
<trace autoflush="true" />
2) 并将其添加到您的 serviceModel 标签中。请务必启用所有消息,当然还有 logMessagesAtTransportLevel,因为这样您就会看到您的消息是如何通过网络发送的。
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="64000"/>
</diagnostics>
3) 最后的配置文件如下所示
- MutualCertificate:因为消息在发送前签名,在收到时签名,有 2 个不同的凭据,但那是
在端点出价中指定
- messageProtectionOrder: 使 wcf 对消息进行加密和签名
- defaultAlgorithmSuite:因为 .NET 使用的算法不是这个 java 服务器
- allowSerializedSigningTokenOnReply:因为响应也被签名了
- requireClientCertificate: 将客户端证书发送到服务器
- ExInspector: 需要操作信封中的 TO
- clientVia:因为它正在与中间路由器通信
最后但不是租约:此服务器向我发送空操作,所以我不得不 fiddle 使用生成的代理 class。
<bindings>
<customBinding>
<binding name="WsHttpSoap11" >
<transactionFlow />
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<security authenticationMode="MutualCertificate"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
messageProtectionOrder="EncryptBeforeSign"
defaultAlgorithmSuite="TripleDesRsa15"
allowSerializedSigningTokenOnReply="true" >
</security>
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://other-endpoint-then-servername" binding="customBinding"
bindingConfiguration="WsHttpSoap11" contract="ProductService"
name="ProductServiceSoap11" behaviorConfiguration="myServiceBehaviour">
<identity>
<dns value="serverdnsname" />
</identity>
</endpoint>
</client>
<extensions>
<behaviorExtensions>
<add name="ExInspector" type="TestService.ExClientBehaviorExtensionElement, TestService"/>
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="myServiceBehaviour">
<clientCredentials>
<clientCertificate findValue="clientcertificatename" storeLocation="CurrentUser" x509FindType="FindBySubjectName" storeName="My" />
<serviceCertificate >
<defaultCertificate storeLocation="CurrentUser" storeName="My" findValue="servercertificatename" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
<clientVia viaUri="https://serverdnsname" />
<ExInspector />
</behavior>
</endpointBehaviors>
</behaviors>
如果对该主题有任何疑问,请随时与我联系。看看这个博客,它对我帮助很大:http://webservices20.blogspot.be/2012/06/12-common-wcf-interop-confusions.html
对于一个项目,我们正在从荷兰连接到 KVK Handelsregister 数据服务。我们已经设置了一个 WCF 客户端代理 class,但是我们的 soap 信封仍然与他们要求的信封不同,任何解决这 3 个问题的想法:
- 删除 mustUnderstandAttribute
- body元素中没有命名空间(ns:)
- header也没有对OASIS的引用
我们的信封:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://es.kvk.nl/genereerProduct</a:Action>
<a:MessageID>urn:uuid:173035b3-714d-46ef-96c2-1d46962ec897</a:MessageID>
<ActivityId CorrelationId="3d2fb1c7-99db-4c88-9745-6cd187281fc6" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">5f48b058-21d5-46c4-8a8b-02f60556ef0e</ActivityId>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://es.kvk.nl/KVK-DataserviceCT/2012/10</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<genereerProduct xmlns="http://schemas.kvk.nl/schemas/hrip/generiekproduct/2013/01">
<productRequest>
<klantreferentie>QW43BA12</klantreferentie>
<productnaam>Inschrijving</productnaam>
<productsleutel>
<kvkNummer>01048900</kvkNummer>
</productsleutel>
</productRequest>
</genereerProduct>
</s:Body>
</s:Envelope>
应有的信封
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:ns="http://schemas.kvk.nl/schemas/hrip/generiekproduct/2013/01"
xmlns:add="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<add:Action>http://es.kvk.nl/genereerProduct</add:Action>
<add:MessageID>uuid://94-b0e0-d4313c898af0</add:MessageID>
<add:To>http://es.kvk.nl/KVK-DataserviceCT/2012/10</add:To>
</soapenv:Header>
<soapenv:Body>
<ns:genereerProduct>
<ns:productRequest>
<ns:klantreferentie>QW43BA12</ns:klantreferentie>
<ns:productnaam>Inschrijving</ns:productnaam>
<ns:productsleutel>
<ns:kvkNummer>01048900</ns:kvkNummer>
</ns:productsleutel>
</ns:productRequest>
</ns:genereerProduct>
</soapenv:Body>
</soapenv:Envelope>*
按照下面评论中的要求,wsHttpBinding 和 customBinding 的绑定配置。更改此设置对 soap 信封没有影响,自定义绑定的错误是:
ERROR An error occurred while receiving the HTTP response to https://webservices 8.kvk.nl/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more de tails.
<bindings>
<wsHttpBinding>
<binding name="ProductServiceSoap11">
<security mode="Transport">
<message clientCredentialType="Certificate"/>
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
<customBinding>
<binding name="WsHttpSoap11" >
<transactionFlow />
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
至少我找到了正确的配置并让这个 link 工作。毕竟摆弄 SOAP 信封只是此连接的整个解决方案的一部分。
但我会添加一些信息,这对我的工作有很大帮助。
1) 日志记录,将其添加到您的配置文件中以启动日志记录
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information,ActivityTracing"
propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="c:\TestKVKService\TestKVKService\bin\Debug\Log\Tracesmore.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="xml" />
</sharedListeners>
<trace autoflush="true" />
2) 并将其添加到您的 serviceModel 标签中。请务必启用所有消息,当然还有 logMessagesAtTransportLevel,因为这样您就会看到您的消息是如何通过网络发送的。
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="64000"/>
</diagnostics>
3) 最后的配置文件如下所示
- MutualCertificate:因为消息在发送前签名,在收到时签名,有 2 个不同的凭据,但那是 在端点出价中指定
- messageProtectionOrder: 使 wcf 对消息进行加密和签名
- defaultAlgorithmSuite:因为 .NET 使用的算法不是这个 java 服务器
- allowSerializedSigningTokenOnReply:因为响应也被签名了
- requireClientCertificate: 将客户端证书发送到服务器
- ExInspector: 需要操作信封中的 TO
- clientVia:因为它正在与中间路由器通信
最后但不是租约:此服务器向我发送空操作,所以我不得不 fiddle 使用生成的代理 class。
<bindings>
<customBinding>
<binding name="WsHttpSoap11" >
<transactionFlow />
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<security authenticationMode="MutualCertificate"
messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
messageProtectionOrder="EncryptBeforeSign"
defaultAlgorithmSuite="TripleDesRsa15"
allowSerializedSigningTokenOnReply="true" >
</security>
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://other-endpoint-then-servername" binding="customBinding"
bindingConfiguration="WsHttpSoap11" contract="ProductService"
name="ProductServiceSoap11" behaviorConfiguration="myServiceBehaviour">
<identity>
<dns value="serverdnsname" />
</identity>
</endpoint>
</client>
<extensions>
<behaviorExtensions>
<add name="ExInspector" type="TestService.ExClientBehaviorExtensionElement, TestService"/>
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="myServiceBehaviour">
<clientCredentials>
<clientCertificate findValue="clientcertificatename" storeLocation="CurrentUser" x509FindType="FindBySubjectName" storeName="My" />
<serviceCertificate >
<defaultCertificate storeLocation="CurrentUser" storeName="My" findValue="servercertificatename" x509FindType="FindBySubjectName" />
</serviceCertificate>
</clientCredentials>
<clientVia viaUri="https://serverdnsname" />
<ExInspector />
</behavior>
</endpointBehaviors>
</behaviors>
如果对该主题有任何疑问,请随时与我联系。看看这个博客,它对我帮助很大:http://webservices20.blogspot.be/2012/06/12-common-wcf-interop-confusions.html