在WCF中处理肥皂信封

最后发布: 2015-06-10 08:47:52


问题

对于一个项目,我们将连接到荷兰的KVK Handelsregister DataService。 我们已经设置了WCF客户端代理类,但是我们的肥皂信封仍然与他们要求的信封有所不同,任何想法都可以解决以下3个问题:

  1. 删除mustUnderstandAttribute
  2. 主体在元素中没有名称空间(ns :)
  3. 标头也没有对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的绑定配置。 更改此设置对肥皂信封没有影响,自定义绑定的错误是:

错误收到对https:// webservices 8.kvk.nl/的HTTP响应时发生错误。 这可能是由于服务端点绑定未使用HTTP协议。 这也可能是由于服务器终止了HTTP请求上下文(可能是由于服务关闭了)。 有关更多详细信息,请参阅服务器日志。

<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>
c# wcf soap
回答

至少我找到了正确的配置并使此链接正常工作。 毕竟,摆弄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 :因为它正在与中间路由器通信

最后但不是租约:该服务器向我发送了空操作,因此我不得不摆弄生成的代理类。

     <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