Friday, 23 October 2015

Basic Authentication in WCF REST on IIS

A complete guide to create secure WCF REST API with custom Basic Authentication

WCF REST API services are still being used by many developers for client server connectivity for data and messaging. This blog is a complete guide on creating a WCF Rest service from scratch and Adding security to the service using Basic Authentication. Then we’ll learn how to encrypt the basic authentication information which would be sent over the network using SSL. The main sections of this guide are:

Pre-requisite:

  • Basic knowledge of Visual studio/WCF basics.
  • Visual studio version > 2008
  • .Net framework > 3.5 installed
  • IIS server >7 or equal

Adding Basic authentication

The REST services are built and run over http protocol. A simple way to enable the authentication is to use Basic Authentication(i.e. user/pwd). Basic authentication can be enabled over http protocol. Now here are the choices that we have:

We can use simple transport level basic authentication by using Custom username and password validator as mentioned here. But the author has explicitly stated that this will only work in self hosted environment. Which is not our case as we are using IIS to host our service. Also there are other method available on the internet like by extending ServiceAuthenticationManager or using a custom MessageInspector and use it like a custom user/pwd validator but I was not really convinced with those methods because somehow they were not best candidate for our scenario. The challenge comes with IIS is that IIS does the authentication before WCF receives the request. And Till now there’s no out of the box support for Basic Authentication for WCF REST on IIS. So we have to go with our custom solution which is by extending ServiceAuthorizationManager class and override method CheckAccessCore and using it in Service Behaviors as default Authorization manager. The configuration would look something like below after setting up a custom service Authorization manager.

      <serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization
serviceAuthorizationManagerType
=" WcfWebHttpIISHostingSample.RestAuthorizationManager, WcfWebHttpIISHostingSample"/>
</behavior>
</serviceBehaviors>
Now I have to extend the class ServiceAuthorizationManager with a custom class RestAuthorizationManager which I named it to make sense with the context.
   public class RestAuthorizationManager : ServiceAuthorizationManager
{
/// <summary>
/// Method source sample taken from here: http://bit.ly/1hUa1LR
/// </summary>
protected override bool CheckAccessCore(OperationContext operationContext)
{
//Extract the Authorization header, and parse out the credentials converting the Base64 string:
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if ((authHeader != null) && (authHeader != string.Empty))
{
var svcCredentials = System.Text.ASCIIEncoding.ASCII
.GetString(Convert.FromBase64String(authHeader.Substring(6)))
.Split(':');
var user = new { Name = svcCredentials[0], Password = svcCredentials[1] };
if ((user.Name == "testuser" && user.Password == "testpassword"))
{
//User is authrized and originating call will proceed
return true;
}
else
{
//not authorized
return false;
}
}
else
{
//No authorization header was provided, so challenge the client to provide before proceeding:
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm=\"MyWCFService\"");
//Throw an exception with the associated HTTP status code equivalent to HTTP status 401
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
}
Now your application is ready to challenge any request with Basic Authentication. To test it you can use any client like Fiddler or Chrome’s post man plugin and see what outcome you get. Let’s simply make a request from normal browser, I’ll get a challenge for basic authentication prompting user/password.

clip_image002

Enter the username - testuser and password – testpassword which we have used to validate the values in our RestAuthorizationManager class.

clip_image004

Continue to – Using Https and SSL to encrypt the Basic authentication information, Creating a self signed certificate and Setup IIS and configure WCF REST Service.


Or Download the complete tutorial Guide as PDF from here.