10

I need to call some 3rd Web services that require WS-Security. I created a WCF endpoint with the following configuration:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="TestBinding">
        <security mode="TransportWithMessageCredential">
          <message clientCredentialType="Certificate" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="TestBehavior">
        <callbackDebug includeExceptionDetailInFaults="true" />
        <clientCredentials>
          <clientCertificate findValue="Acme" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" />
          <serviceCertificate>
            <authentication certificateValidationMode="PeerOrChainTrust" />
          </serviceCertificate>
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <client>
    <endpoint address="https://acme.com/webservices" binding="wsHttpBinding" bindingConfiguration="TestBinding" behaviorConfiguration="TestBehavior" contract="AcmeContract" name="AcmeEndpoint"></endpoint>
  </client>
</system.serviceModel>

The problem is that the 3rd party servers a throwing the following exception:

Received protocol '_http://schemas.xmlsoap.org/wsdl/soap12/', required protocol '_http://schemas.xmlsoap.org/wsdl/soap/'.

I understand that using the wsHttpBinding will cause WCF to send a SOAP 1.2 request while using the basicHttpBinding will result in a SOAP 1.1 request. Since the WS-Security parts are required, as I understand it, I have to use the wsHttpBinding. My question is how do I force a SOAP 1.1 request? What are my options?

Stefan Moser
  • 6,663
  • 9
  • 35
  • 48

2 Answers2

13

In order to use WS-Addressing (wsHttpBinding), but with SOAP 1.1 (SOAP 1.2 being the default), you need to define a custom WCF binding (e.g. in config) and use that:

<bindings>
   <customBinding>
      <binding name="WsHttpSoap11" >
         <textMessageEncoding messageVersion="Soap11WSAddressing10" />
         <httpTransport/>
      </binding>
   </customBinding>
</bindings>

and then in your endpoint definition, use:

<endpoint name="WsSoap11"
    address="....."
    binding="customBinding"
    bindingConfiguration="wsHttpSoap11"
    contract="....." />

Of course, you can extend the custom binding defined above with additional properties, e.g. <reliableMessaging> or others.

For more very detailed, very useful info on WCF bindings and how to "compose" your own custom bindings in config, read this excellent MSDN article Service Station: WCF Bindings In Depth by Aaron Skonnard.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    This just helped me immensely to create an endpoint that uses SOAP1.2 and Aug 2004 WS-Addressing. Filled in that final little gap that made it click for me! – squillman Apr 16 '13 at 21:07
  • This answer was just what I needed to fix the error: (415) Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'. – Matt Kemp Oct 11 '13 at 04:44
  • -1: This will not work with an HTTPS address, since the transport used in the custom binding is for HTTP. – reSPAWNed Aug 15 '14 at 11:24
  • 2
    @reSPAWNed: So what? Replace `` with ``. – Marcel N. Aug 25 '14 at 14:11
7

You must either use BasicHttpBinding which also supports TransportWithMessageCredentials (SOAP 1.1 + HTTPS + WS-Security X.509 Certificate Token profile) or create custom binding based on all your needs.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • I've tried changing the wsHttpBinding to basicHttpBinding, but it causes an exception and doesn't make it to the 3rd party server. From what I've read, basicHttpBinding is incompatible with certificate authenticate. Am I wrong? – Stefan Moser Mar 23 '11 at 23:02
  • MSDN says that certificate authentication is supported: http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpmessagecredentialtype.aspx – Ladislav Mrnka Mar 23 '11 at 23:33