Welcome to Manicprogrammer Sign in | Join | Help

WCF and ClientCredentialType of UserName- Don't Forget the bindingConfiguration attribute

I thought I'd share a silly little hiccup and easy oversight I encountered in developing a guidance project against WCF.

I am doing some work this weekend with building out a pattern and standard for some WCF authentication protocols for the organization I work for. We have some web services that are used by both internal and external users and are moving these over to WCF. One of the areas I am charting out is the use of message level security with the ClientCredentialType set to UserName. I was shocked when it appeared to have worked right out of the box even though I knew I left out what was supposed to be a required step- the creation, installation and registration of the x.509 certificate.

Using a test approach of fail first- I was trying to see it fail first then make the changes to pass. This is especially helpful as I am trying to document a set of repeatable steps for others to apply to start from scratch and get going as well as how to prepare shared infrastructure. I wanted to ensure I was starting from a position in which this would not work (the assumed position for each new machine to be configured)

I created a sample WCF Service Application project and added in a single method called Ping that did nothing but accept a call and return the string "Ping". In the web.config I created a binding as follows:

   1: <wsHttpBinding>
   2:     <binding name="WSHttpUserName">
   3:         <security>
   4:             <transport clientCredentialType="None" />
   5:             <message clientCredentialType="UserName" />
   6:          </security>
   7:     </binding>
   8: </wsHttpBinding>
Figure 1.

 

I created a quick test harness web form to call into the Ping method of the new service and added a Service Reference. For the record, I normally create a proxy and also use unit tests versus this more manual and non-automated approach but I am wanting to experiment and play - not formally test. It's more of a proof of concept than a prototype. I expected that as soon as I hit the service I'd get an exception from the service related to the situation that I had not set up the x.509 certificate. Even if I had setup the certificate I had expected it would fail one step further as no provider had been established to validate the passed username and password. I programmed my client to set a UserName and Password of the client credentials. I called the service on my local machine with my playground client and to my surprise up popped the "Ping" string it had returned.  What?!! My first thought was that somehow it was not using the message level security. Unfortunately, Fiddler doesn't allow me to see the traffic sent to localhost so I pushed this out to a different machine, spun up Fiddler and tried again. This time I called the remote service and got back the same results. Looking at the traffic in Fiddler the expected handshaking for security tokens and subsequent message level encryption was occurring. How could that be - where was this token for communication coming from?

After a few minutes I realized a simple and ridiculous mistake. Even though I had set a binding definition for wsHttpBinding it was not being used as I had not set on the server the <endpoint> bindingConfiguration attribute to the name of that binding. I knew that wsHttpBinding defaults to message level security with Windows as the clientCredentialType but didn't catch on right away that was happening.  The binding I had defined was not being used. The default Windows credentials were being used. That's why I was seeing message level security and encryption in the communication. I am a valid windows user on both the machines. I set the bindingConfiguration attribute to the binding name I had established and I tested against (Figure 2).  Once I did this I got the expected failure from the lack of a certificate.

 

   1: <endpoint address="" binding="wsHttpBinding" bindingConfiguration="WSHttpUserName" ...
Figure 2

 

Even if I had thought about the bindingConfiguration attribute I might have falsely assumed that if I set up any <binding> under the <wsHttpBinding> (Figure 1) that it might be the default. That assumption would break down as soon as you define more than one <binding>- which would now be the default? It makes perfect sense that I needed to define the bindingConfiguration.

Thought I would share with others both a good example of where 'fail first' in testing (formal or otherwise) saves the day. I could have easily not realized until it was late in the process that I was not operating under the mechanism I intended.  In addition thought this might be valuable to someone as a hint to not forget to set you bindingConfiguration appropriately when you modify your bindings from the default.

Published Saturday, October 11, 2008 1:39 PM by michaelruminer
Filed under

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Enter the text you see in the image:

Leave a Comment

(required) 
required 
(required)