How To Implement Basic Authentication For MVC WebApi Application

Recently I started working on a MVC WebApi project. We decided to use Basic Authentication as our authentication mechanism between client and server. Yes, I am aware of the fact that Basic Authentication mechanism is not the greatest and most secure mechanism. But for the conditions under which communication is going to take place, this was simplest authentication mechanism to get the ball rolling. Later on, we will look at more secure mechanism based on claims and assertions (SAML2 etc.).

What is Basic Authentication

You can read more details about basic authentication mechanism on w3.org site. In most simplest terms, for basic authentication to work a client application puts login credentials in Authorization header. The credentials are specified as Base64 encoded key-value pair. Following is an example that shows how this header may look like

Authorization: Basic QWxpZGRpbjpvsGVuIHNlc4FtZQ==

Client code to send basic authentication header

Before go ing deep into how server side MVC WebApi will handle authentication and authorization for basic authentication mechanism, i will show you some client side code that used to set the credentials in requests that are being made to a MVC WebApi from another MVC web application.

public static void SetBasicAuthentication(HttpClient client, string username, string password)
{
    var bytes = System.Text.Encoding.ASCII.GetBytes(string.Format("{0}:{1}", username, password));
    var encodedCredntials = Convert.ToBase64String(bytes);
    client.DefaultRequestHeaders.Add("Authorization", string.Format("Basic {0}", encodedCredntials));
}
    

As you can see from the code about how key-value pair for credentials is being constructed and set in the header.

Custom AuthorizeFilter in MVC WebApi

Now we will look at what do we need to do on server side to authenticate and authorize a request. First it is important to know what for Web Api, AuthorizeAttribute needs to be used from System.Web.Http namespace and not from System.Web.Mvc namespace. If you will decorate your controller with System.Web.Mvc.AuthorizeAttribute, framework will ignore it.

First step would be to create a custom authorization class that derives from System.Web.Http.AuthorizeAttribute. Then override OnAuthorize method to implement your authentication and authorization. If request is not authorized then you will set appropriate HttpResponseMessage in context and framework will return 401 status code back to client with whatever reason phrase you set in response. Following code from my application shows how this is implemented.

 public class PartnerAuthorizeAttribute : AuthorizeAttribute
 {
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (!AuthorizeCore(actionContext))
        {
          actionContext.Response = new System.Net.Http.HttpResponseMessage()
          {
            StatusCode = System.Net.HttpStatusCode.Unauthorized,
            RequestMessage = actionContext.Request
          };
          actionContext.Response.Headers.Add("WWW-Authenticate", 
              "Basic realm=\"Trader Service\"");
          actionContext.Response.ReasonPhrase = "Unauthorized request";
        }
   }

   private bool AuthorizeCore(HttpActionContext actionContext)
   {
      // Check if Authorization header is present.
      var authHeader = actionContext.Request.Headers.Authorization;
      if (null == authHeader ||
          string.IsNullOrWhiteSpace(authHeader.Scheme) ||
          authHeader.Scheme != "Basic" ||
          string.IsNullOrWhiteSpace(authHeader.Parameter))
      {
        return false;
      }

      // Get login credentials.
      var encodedCredentials = authHeader.Parameter.Replace("Basic ", "");
      var credentialBytes = Convert.FromBase64String(encodedCredentials);
      // Basic authentication header has login as "username:password" pair.
      var credentials = System.Text.Encoding.ASCII.GetString(credentialBytes).Split(':');
      if (credentials.Length != 2)
      {
          return false;
      }
      var login = credentials[0];
      var password = credentials[1];
      var membershipProvider = new MembershipProvider();
      return membershipProvider.ValidatePartner(login, password);
  }
}
    

Set attribute on controller

Now we have only one last step left to get your WebApi controller to enforce basic authentication. Decorate controller with this custom attribute. Once the attribute is set on method, each request for controller will be authorized by your custom implementation.

 [PartnerAuthorize]
 [HttpPost]
 [RequestValidationFilter]
 public HttpResponseMessage PostSettings(SettingsRequestParameters requestParameters)
 {......}
    

I hope this provides you some insight into how to implement custom authorization for your MVC WebApi requests.

Search

Social

Weather

17.9 °C / 64.3 °F

weather conditions Mist

Monthly Posts

Blog Tags