Niraj Bhatt – Architect’s Blog

Ruminations on .NET, Architecture & Design

Username Authentication over basicHttpBinding with WCF’s ChannelFactory Interface

HTTP/HTTPS holds good (add no session management) for lot of people today & they prefer using them as their transport protocol for WCF Services. Many a time users connecting with your service are outside your domain so you will like to authenticate them with username / password. This is where WCF makes things difficult.

There is some support shown here for self hosted service (but I have my own reservations over that as IIS is the most preferred hosting mechanism when it comes to HTTP). Let me split this post into 2 parts – assigning credentials to client & authenticating those credentials on server (N.B. my writing is on top of custom binding + channel interface, no Add Service Reference used).

1) Adding credentials on client side via channel factory interface:

ClientCredentials is part of System.ServiceModel.Description.ClientCredentials (System.ServiceModel). Problem is ChannelFactory has a readonly ClientCredentials Property (not when you generate proxy by inheriting from ClientBase this is simplified for you). Luckily there is a workaround. To start with you can instantiate it & assign required values

ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = “Niraj”;
loginCredentials.UserName.Password = “Password123″;

Now ClientCredentials are by default endpoint behaviors, so you have remove the default one & attach the newly created one. Below code shows that

var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
factory.Endpoint.Behaviors.Remove(defaultCredentials); //remove default ones
factory.Endpoint.Behaviors.Add(loginCredentials); //add required ones

 2) Authenticating Credentials on Server Side: This is where things get tricky and you need to use something probably you have heard of but haven’t tried yet, a WCF security mode called – TransportWithMessageCredential (N.B. It’s not currently possible to handle this scenario using Basic Authentication of IIS (transport clientCredentialType), though you can easily do it for REST).

Step 1 is your customize your binding (this has to be done on both Server & Client configurations)

<bindings>
      <basicHttpBinding>
        <binding name=”usernameHttps”>
          <security mode=”TransportWithMessageCredential”>
            <message clientCredentialType=”UserName”/>
          </security>
        </binding>
      </basicHttpBinding>
</bindings>

Note that the above would force you to use HTTPS but anyways that’s a recommended approach also. Now it’s time to go to your service and specify the service credentials as shown below, here we use custom authenticator but you could as well used provider model of ASP.NET,

<serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode=”Custom”
              customUserNamePasswordValidatorType=”…” />
</serviceCredentials>

public class CustomPass : UserNamePasswordValidator //System.IdentityModel.dll
{
        public override void Validate(string userName, string password)
        {
            //your validation here, throw exception if invalid user
        }
}

That’s it. You are all set. Fire you client & you have username authentication over HTTPS. Hope that helps.

(N.B. You can check my blog entry about how to configure HTTPS for WCF on IIS)

May 22, 2009 - Posted by nirajrules | Windows Communciation Foundation | , | 2 Comments

2 Comments »

  1. I don’t get step 1, why this way if you just can set it like this:

    factory.Credentials.UserName.UserName = “somthing”;
    factory.Credentials.UserName.Password = “somthing”;

    Regards,
    CA

    Comment by CA | June 9, 2009 | Reply

  2. Hi CA,

    I already mentioned that while using channel factory interface, – “Problem is ChannelFactory has a readonly ClientCredentials Property”. I guess what you are saying will only work if you are using Add Service Reference & ClientBase inheritance, which would handle it for you behind the covers. In my scenario I have some limitation on using Add Service Reference.

    Comment by nirajrules | June 10, 2009 | Reply


Leave a comment