Supertext Home
Chief of the System Blog

Basic Http Authorization for Web API in MVC 4 Beta

April 19th, 2012 by

A little while ago I posted a solution to do Basic Http Authorization with the Web API Preview 6. Web API got then merged into the next ASP.NET MVC 4 Beta Release and in the process has changed a lot.

Since my old approach did not work anymore, I had to create something new.



public class OrderController : ApiController
    // GET /api/orders/5
    [BasicHttpAuthorizeAttribute(RequireAuthentication = true)]
    public string Get(int id, string communicationLang)
        //do your API Stuff

And the Authentication class itself:

public class BasicHttpAuthorizeAttribute : System.Web.Http.AuthorizeAttribute  
    bool requireSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["RequireSsl"]);
    public bool RequireSsl
        get { return requireSsl; }
        set { requireSsl = value; }
    bool requireAuthentication = true;
    public bool RequireAuthentication
        get { return requireAuthentication; }
        set { requireAuthentication = value; }
    /// <summary>
    /// For logging with Log4net.
    /// </summary>
    private static readonly ILog log = LogManager.GetLogger(typeof(BasicHttpAuthorizeAttribute));
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)        
        if (Authenticate(actionContext) || !RequireAuthentication)
    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
        var challengeMessage = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        challengeMessage.Headers.Add("WWW-Authenticate", "Basic");
        throw new HttpResponseException(challengeMessage);
        //throw new HttpResponseException();
    private bool Authenticate(System.Web.Http.Controllers.HttpActionContext actionContext) //HttpRequestMessage input)
        if (RequireSsl && !HttpContext.Current.Request.IsSecureConnection && !HttpContext.Current.Request.IsLocal)
            log.Error("Failed to login: SSL:" + HttpContext.Current.Request.IsSecureConnection);
            return false;
        if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization")) return false;
        string authHeader = HttpContext.Current.Request.Headers["Authorization"];
        IPrincipal principal;
        if (TryGetPrincipal(authHeader, out principal))
            HttpContext.Current.User = principal;
            return true;
        return false;
    private bool TryGetPrincipal(string authHeader, out IPrincipal principal)
        var creds = ParseAuthHeader(authHeader);
        if (creds != null)
            if (TryGetPrincipal(creds[0], creds[1], out principal)) return true;
        principal = null;
        return false;
    private string[] ParseAuthHeader(string authHeader)
        // Check this is a Basic Auth header 
        if (authHeader == null || authHeader.Length == 0 || !authHeader.StartsWith("Basic")) return null;
        // Pull out the Credentials with are seperated by ':' and Base64 encoded 
        string base64Credentials = authHeader.Substring(6);
        string[] credentials = Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(new char[] { ':' });
        if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[0])) return null;
        // Okay this is the credentials 
        return credentials;
    private bool TryGetPrincipal(string username, string password, out IPrincipal principal)
        // this is the method that does the authentication 
        //users often add a copy/paste space at the end of the username
        username = username.Trim();
        password = password.Trim();
        //Replace this with your own Authentication Code
        Person person = AccountManagement.ApiLogin(username, password);
        if (person != null)
            // once the user is verified, assign it to an IPrincipal with the identity name and applicable roles
            principal = new GenericPrincipal(new GenericIdentity(username), System.Web.Security.Roles.GetRolesForUser(username));
            return true;
            if (!String.IsNullOrWhiteSpace(username))
                log.Error("Failed to login: username=" + username + "; password=" + password);
            principal = null;
            return false;

You will have to adjust the TryGetPrincipal() method to include our own Authorization code that works with your system. Or maybe plain normal ASP.NET Provider Authentication is enough in your case.

You can download the code from github:

23 Comments to “Basic Http Authorization for Web API in MVC 4 Beta”

  • Ivan says on June 9th, 2012 at 11:31 am :

    Puting authentication in my rest service it has been a nightmare. Thanks a lot for your post.

  • Chris says on June 24th, 2012 at 4:25 pm :

    This code works fine under the built in web server in Visual Studio 2010 but it does NOT work under IIS 7.5 by default.

    To get it to work under IIS 7.5, you need to turn off all authentication mechanisms for your website within IIS EXCEPT “Anonymous Authentication”. See

    This class is basically rolling its own basic http authentication and having IIS’s auth mechanisms enabled seems to cause a conflict.

  • Rémy Blättler says on June 25th, 2012 at 3:19 am :

    Thanks for your hint. I forgot to mention that.

  • george says on July 3rd, 2012 at 5:37 am :

    Two things.

    1. I’m never getting a value of True for RequireAuthentication . It’s always false.

    2. On one of my controllers the OnAuthorization method gets called twice.


  • Rémy Blättler says on July 3rd, 2012 at 5:41 am :

    You’ve set it up like this:
    [BasicHttpAuthorizeAttribute(RequireAuthentication = true)]

    And this does not come through? Cause this is just basic framework functionality.

  • george says on July 9th, 2012 at 2:43 am :

    I had an unrelated problem. Works great.

  • Sam says on July 19th, 2012 at 12:15 pm :

    Thanks for the post this has been very helpful.

    I am having one issue. I set HttpContext.Current.User = principal in the Authenticate however in my controller this.User.Identity in not set to the principalI set – it is basically blank (IsAuthnticated = False and Name = “”). This is a problem as I need this information in my controller.

    Is something overwriting it?

  • Rémy Blättler says on July 23rd, 2012 at 9:38 pm :

    Not that I know of. Did you try Membership.GetUser()?

  • Sam says on July 24th, 2012 at 10:56 am :

    Unfortunately I am not using the membership provider. I am using a custom authentication solution and I would like the assign the username of the authenticated user to HttpContext.Current.User.

  • Rémy Blättler says on July 24th, 2012 at 2:05 pm :

    Right. That should be possible where I do this:


    Just replace my authentication code with your solution.

  • Basic Authentication with WCF Web API Preview 6 | Chief of the System Blog says on July 30th, 2012 at 5:56 pm :

    [...] Basic Http Authorization for Web API in MVC 4 Beta [...]

  • Lelala says on April 4th, 2013 at 11:03 am :

    Wow, better example than the one supplied by Microsoft themselves. Thanks for shortening their version :-)

  • Ajosh says on May 3rd, 2013 at 2:36 pm :

    Thanks a lot. This helped me a lot.

  • xiaobao says on May 21st, 2013 at 6:16 pm :


    I get an error on GenericPrinciple line

    The Role Manager feature has not been enabled.

    I am using a custom database(not membership). Can I use that part what you wrote? If so how do I fix this error?

  • Rémy Blättler says on May 22nd, 2013 at 3:42 am :

    Do you use a totally different authentication method? E.g. you never us the Membership and Role classes?
    Then you just have to change a few more places and get rid of the IPrincipal stuff completely and replace it with your own authentication code.

  • xiaobao says on May 22nd, 2013 at 12:48 pm :


    As right now I have my own role and user table and not using any of the built in stuff as I guess I would have to write my own membership stuff then.

    Ok then I will just replace it with my own code. I am not sure if this is what you where going for with “RequireAuthentication” property you have but maybe you should add to this the AllowAnonymous check so that attribute can be used.

    private static bool SkipAuthorization(HttpActionContext actionContext)
    Contract.Assert(actionContext != null);

    return actionContext.ActionDescriptor.GetCustomAttributes().Any()
    || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes().Any();

  • Rémy Blättler says on May 23rd, 2013 at 3:06 am :

    Yes, if you omit the RequireAuthentication attribute (you can define it on method or class level) it will allow for anonymous users.

  • James says on June 24th, 2013 at 5:31 pm :

    Thanks for your post! Just used this to secure my API and it works well.

  • MAttias Bomelin says on September 30th, 2013 at 7:40 pm :

    Is it possible to use it in combination with Authorize(Users=”xx”) or Authorize(Roles=”yy”) to only allow certain users/roles access to one action?

  • Rémy Blättler says on October 1st, 2013 at 4:16 am :

    That is currently not included. You would have to build that yourself.

  • Chris Nevill says on July 6th, 2014 at 7:31 am :

    I’m starting from the ASP.NET Web API template in Visual Studio 2013 Update 2.

    The BasicAuthorization Attribute is just completely ignored and control passes into the action without being authorized.

    I’ve followed the other recommendations here to ensure only Annonymous Auth is enabled in IIS, but it makes no difference. I definitely have the attribute marked on the action in my controller. Is there anything else I have to do?

  • Chris Nevill says on July 6th, 2014 at 7:33 am :

    Ps your spam protection doesn’t make it clear you need to enter digits. I was asked the sum of one plus eight – so I entered “nine”. It took me about 6 attempts before I realised it was looking for ints rather than a string!

  • Chris Nevill says on July 6th, 2014 at 8:10 am :

    Ah I’ve figured it out. I was actually placing the authentication on an MVC controller (Home) rather than a WEB API controller (Values).

    For an MVC controller you would need to use System.Web.MVC.AuthorizeAttribute instead of System.Web.Http.AuthorizeAttribute.

    Thanks for the blog.

Leave a Reply

  • Topics
  • Archive
  • Subscribe
  • Facebook
  • Twitter