Tuesday, March 17, 2009

Which Binding to Use - WSHttpBinding or WS2007HttpBinding?


The default binding in Wcf 3.0 is WSHttpBinding. Wcf 3.5 brings the new WS2007HttpBinding binding but WSHttpBinding is still the default. These bindings do not interoperate together well due to the fact that WS2007HttpBinding uses some newer standards.

When the client uses WS2007HttpBinding and the server employs WSHttpBinding we may get this exception in the client side:

Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.

And the inner exception is:

"The message could not be processed. This is most likely because the action 'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding."

On the server side trace we see

System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089

And the inner exception:

There was no channel that could accept the message with action 'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue'.

When the client uses WSHttpBinding and the server employs WS2007HttpBinding we would get the same exceptions with http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue being replaced by http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue.

The reason for the errors is the different WS-Trust versions between the bindings. WS-Trust is used when the negotiateServiceCredential or establishSecurityContext settings are set to true (which is the default). In these cases infrastructure messages are exchanged between the client and the server and these messages require the WS-Trust version to match.

We can see the different versions if we use the reflector to check the bindings static constructors.

In WSHttpBinding:

static WSHttpBinding()
  WSMessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005

In WS2007HttpBinding:

static WS2007HttpBinding()
  WS2007MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13

So, which binding to use?
In many cases this does not matter since both bindings expose similar functionality.
You might want to consider the following:

  • WSHttpBinding is supported by .Net 3.0 clients.

  • WS2007HttpBinding uses WS-* standards while WSHttpBinding uses drafts. You might face a requirement to work with the standard.

  • Different soap stacks support different standards so if you need to interoperate with a specific framework verify the standards it supports.

  • In the long run WS2007HttpBinding should be used as it supports the actuall standard.

  • Nevertheless, for most services this decision will probably only have a very minor effect.


    What's next? get this blog rss updates or register for mail updates!


    Anonymous said...

    Hi Yaron,

    good post really resolved the issue for me.

    M Vaqqas

    Splaktar said...

    Thanks for the info.