Wednesday, October 01, 2008

WCF: WS-Security using Kerberos over SSL

WCF support typical scenarios with the system provided bindings such as basicHttpBinding and wsHttpBinding. These bindings work very well in WCF-only environments and for interop scenarios where all parties are completely WS* standard compliant.

However, interop always seems to need some tweaking, and the ootb bindings allow you to change many aspects of the binding configuration. But there will always be scenarios where these bindings just cannot be configured to fit your needs. E.g. if you need a binding that supports custom wsHttp over SOAP1.1 using a non-negotiated/direct Kerberos WS-Security token secured by TLS. In this case you need a custom binding, because e.g. even if you can turn of spnego for wsHttpBinding, you cannot tweak it into using SOAP1.1

WCF <customBinding> to the rescue:

<customBinding>
<binding name="wsBindingCustom">
<security authenticationMode="KerberosOverTransport"

requireDerivedKeys="false"
includeTimestamp="true">
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>


This custom binding combines HTTPS transport with direct Kerberos.
The timestamp is required for security reasons when using authentication mode Kerberos over SSL. Note that using the UPN/SPN type <identity> element is only supported NTLM or negotiated security, and cannot be used with direct Kerberos.

WCF by default requires that the response always contain a timestamp when it is in the request. This is a typical interop issue with e.g. WSS4J, Spring-WS and WebSphere DataPower.

The response with the signed security header timestamp should be like this:
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp wsu:Id="uuid-c9f9cf30-2685-4090-911b-785d59718267" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2008-09-29T12:02:59Z</wsu:Created>
<wsu:Expires>2008-09-29T12:12:59Z</wsu:Expires>
</wsu:Timestamp>



Note the casing of the wsse: and wsu: namespace elements and attributes. This replay attack detection timestamp can be turned off using the includeTimestamp attribute, or it can be configured using the <localClientSettings> and <localServiceSetting> security elements.

Refer to the <security> element of the <customBinding> documentation for more details. Also review the settings for initiating a WS-SecureConversation if a session is needed.

2 comments:

Anonymous said...

My client (Java) get an exception
when I configure my provider as your example!

"An error occurred when verifying security for the message"

I believe it is because they cannot sign the request.


How can I disable signature from the request?

We use a STS to exchange between tokens. In my log I can see that they can log in to windows server with kerberos, but WCF refuse the connection.

regards/Hamid, Denmark

Kjell-Sverre Jerijærvi said...

The only way to control this outside binding configuration, is to set the ProtectionLevel attribute on the operations.

See the WCF security guide: http://wcfsecurity.codeplex.com/Wiki/View.aspx?title=How%20to%20partially%20encrypt%20a%20message