Saturday, January 3, 2009

How to use clear username/password with WCF?

@YaronNaveh

WCF does not allow to authenticate clients with cleartext username/password. While this is generally considered an unsecured mechanism there are some valid reasons to use it (such as SSL passthrough of load balancers like F5's BIG-IP, or for interoperability reasons). So let's see what can still be done with WCF.

First attempt - using basicHttpBinding with MessageClientCredentialType of "Username".
Unfortunetelly this would yield the following exception:


BasicHttp binding requires that BasicHttpBinding.Security.Message.ClientCredentialType be equivalent to the BasicHttpMessageCredentialType.Certificate credential type for secure messages. Select Transport or TransportWithMessageCredential security for UserName credentials.


Second attempt - using basicHttpBinding with TransportWithMessageCredential mode.

Since this mode implies that we need to secure the transport we get any of these exceptions, depending if we are on the client or the server side:


The provided URI scheme 'http' is invalid; expected 'https'.
Parameter name: via



Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].


Third attempt - using wsHttpBinding with MessageClientCredentialType of "Username".

Depending on several other settings, and wheather we're on the client or the server, we would get any of these exceptions:


Object reference not set to an instance of an object.



The service certificate is not provided for target 'http://localhost/MyWebServices/Services/SimpleService.asmx'. Specify a service certificate in ClientCredentials.



The service certificate is not provided. Specify a service certificate in ServiceCredentials.


Forth attempt - using wsHttpBinding with TransportWithMessageCredential mode.

Similarily to the second attempt we get:


The provided URI scheme 'http' is invalid; expected 'https'.
Parameter name: via


OR


Could not find a base address that matches scheme https for the endpoint with binding WSHttpBinding. Registered base address schemes are [http].


Fifth attempt - using customBinding with httpTransport and security element with authenticationMode of UserNameOverTransport

This time we get:


"The 'CustomBinding'.'http://tempuri.org/' binding for the 'SimpleServiceSoap'.'http://tempuri.org/' contract is configured with an authentication mode that requires transport level integrity and confidentiality. However the transport cannot provide integrity and confidentiality."


So it really seems like Microsoft is trying to (im)politely convince us not to use clear username/password. But what can we do for cases where this behaviour is really required?

The solution

The solution s to use ClearUsernameBinding. This binding seamlessly integrates with WCF and allows us to use clear username/password.

Read more about ClearUsernameBinding for WCF.

@YaronNaveh

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

2 comments:

Unknown said...

This works for :net 3.5 if you need username/password in cleartext over http

binding name="UserPasswordBinding">
security mode="TransportCredentialOnly">
transport clientCredentialType="Basic" />
/security>
/binding>

"<" removed so I could post it.

Cheers
Joakim Eriksson

Yaron Naveh (MVP) said...

Thanks Joakim.

In your case credentials are sent as HTTP headers. However it is sometimes necessary to send them in the SOAP body (as with ClearUsernameBinding).

Of course if you are planing a system from scratch and have no constraints it's better to use what you suggested.