Secure WCF Service on IIS with BasicHttpBinding and Custom Credentials

In one of my current client projects, I had the requirement to secure a WCF service. That is typically an easy requirement but I had a couple of restrictions:

  • Only BasicHttpBinding could be used on the client-side
  • Client credentials (username / password) must be sent and validated with each request

One option is to send and validate the credentials as parameters to each method. This method is usually seen as unacceptable because credentials are passed across the service as plain-text. Do you want your password sent over a web service as plain-text?

After doing some research, I came up with a solution that is largely a combination of two sources: configuring a WCF service on IIS with SSL and username authentication over BasicHttpBinding… I’ll do my best to consolidate both of those sources for simplicity.

Programming / Configuring the WCF Service

  1. Open Visual Studio.
  2. Create a new ‘WCF Service Application’ project.
  3. Define a service interface:
  4. Implement your service interface. Our  GetData method will return a string that shows the authenticated username and the integer value passed. If the current identity is not authenticated, we throw an exception (this is not our validation method, that is shown shortly):
  5. Implement a custom credential validator. The class needs to extend the abstract class  UserNamePasswordValidator . The important implementation detail here is that you want to throw a FaultException  if the credentials are incorrect:
  6. Edit your web config file. This is probably the most tedious portion of the process. I’ll go ahead and attach the whole file here:

    Some important things to note here… We expose two endpoints – one for the BasicHttpBinding and one for service metadata (mex). We are using BasicHttpBinding  with TransportWithMessageCredential  security (that further specifies a message credential type of UserName ). The service credentials point to our CustomValidator . This is the absolute minimum needed for me to get the web service working – all elements were needed.
  7. Publish the project somewhere local on your machine (right-click project, publish).

Configuring IIS for WCF Service with SSL

  1. Follow instructions in this guide, until you reach ‘Configure WCF Service for HTTP Transport Security’ (don’t do that part). I would list these out myself, but I think the visuals provided in the link are very helpful.
  2. I ended up having some file access issues with my application pool, so I ended up making my application pool run as an administrator identity.

 Programming / Configuring the WCF Client

  1. Open Visual Studio.
  2. Create a new ‘Windows Console Application’ project.
  3. Add a new service reference – use the location of your WCF Service that is hosted with IIS. The metadata for the service has been downloaded and an app.config file has been produced. We won’t use the app.config.
  4. Program the console application to make a call to the service:

Happy coding! If you have questions, leave a comment :)

Posted in Professional Tagged with: , , , ,
15 comments on “Secure WCF Service on IIS with BasicHttpBinding and Custom Credentials
  1. harpreet says:

    will the UserNamePasswordValidator ‘s validate function on the server side capable of checking the login credentials in the HTTP headers too??

  2. harpreet says:

    Hi brhlavinka,

    Thanks for your reply.

    clientCredentials.UserName.UserName sends the details in the SOAP header and one of our client is using an old existing enviornment and wants to send the username and password through the http header only.

    i am scratching my head for almost a week now and haven’t found anything in WCF which will authentication the request.

    Do you have any idea??

    • brhlavinka says:

      Based on what I saw in the linked StackOverflow question (from my last reply), you have two options:
      1. Have the client update to send credentials in the expected manner, or
      2. Don’t use the UserNamePasswordValidator and instead use your own logic at the beginning of each WCF method (which should have access to the headers)

      What do you think?

      • harpreet says:

        WOW brhlavinka you are amazing… why i never thought about it…

        you are right if they don’t agree then i will use your advice and check the headers for the login details.

        but this why they have to send the credentials with each request…

        • brhlavinka says:

          Glad to help! Hopefully you’ve made some progress.

          In addition, you are correct about the client needing to send credentials in the header of each request for option 2. If the client were to go with option 1 (using the UserNamePasswordValidator) then they would still need to send the credentials with each call. So both options presented above require the credentials to be sent with each request – just in different manners.

  3. Alma says:

    Dear brhlavinka,
    I do it in the same way but service ignores the certificate. More precisely, the client can use the service without the certificate would be on the client machine.
    Can you help me on it, please?

    • brhlavinka says:

      Hi Alma – I’m not exactly sure what your problem is, but it sounds like the client is able to make calls to the service without providing valid credentials? If that is the case, then you’ll likely need to look into your web config to make sure it’s correct. If you feel that the web config is correct, then perhaps there is a problem with your service hosting within IIS. Feel free to clarify the question if neither of these suggestions help .. good luck! 😀

  4. Huy says:

    Hi mr brhlavinka,

     

    Your lecture is very good, but why I don’t see the UserNamePasswordValidator  abstract class ?

    How can we write it ?

     

    Thank you sir !

  5. Josh says:

    I’ve found myself to the point of removing the default login credentials and adding the appropriate ones, but I am unable to get to where your code example is. My service reference doesn’t show “service.Endpoint.Behaviors” I only have “Endpoint.EndpointBehaviors”. Any idea why and how I can work with this to remove the default credentials?

    Thanks,

    • Josh says:

      After getting the default credentials out and the new credentials in, I’m now getting a “CommunicationObjectFaultedException” from my client calling a method in the service.

      “The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.”

      I read somewhere that this can be caused by invalid permissions. Is this what you were talking about when you mentioned that you elevated your applicationpool user to administrative privileges?

      • brhlavinka says:

        Hey Josh – thanks for commenting! I can’t remember running into this problem, but it’s been a while :) .. I’d definitely try out elevating the Application Pool privileges. Perhaps that’ll help – let us know!

        • Josh says:

          Thanks for your reply to my reply. I ended up figuring it out, but as I’m sure you know, thinking back even 3 weeks when you’re neck deep in an issue can be difficult. I think what actually ended up fixing it was something going wrong with the certificate. I may have had the service asking for a ssl connection yet it wasn’t trusted on my machine or something like that.

          Long story made short I did end up figuring it out, but I will probably need to bang into it again a few times before it is really committed to memory.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Subscribe to my Insights via Email

Join 61 other subscribers

%d bloggers like this: