Search code examples
c#.netauthenticationbasic-authentication

How can I retrieve Basic Authentication credentials from the header?


I am trying to write some simple tests User Authentication mechanism which uses Basic Authentication. How can I retrieve the credentials from the header?

string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];

Where do I go from here? There are several tutorials but I new to .NET and authentication, could you explain in your answer exactly step-by-step the what and why you are doing.


Solution

  • From my blog:

    This will explain in detail how this all works:

    Step 1 - Understanding Basic Authentication

    Whenever you use Basic Authentication a header is added to HTTP Request and it will look similar to this:

    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

    Source: http://en.wikipedia.org/wiki/Basic_access_authentication

    "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" is just "username:password" encoded in Base64(http://en.wikipedia.org/wiki/Base64). In order to access headers and other HTTP properties in .NET (C#) you need to have access to the current Http Context:

    HttpContext httpContext = HttpContext.Current;
    

    This you can find in System.Web namespace.

    Step 2 - Getting the Header

    Authorization header isn't the only only one in the HttpContext. In order to access the header, we need to get it from the request.

    string authHeader = this.httpContext.Request.Headers["Authorization"];
    

    (Alternatively you may use AuthenticationHeaderValue.TryParse as suggested in pasx’s answer below)

    If you debug your code you will see that the content of that header looks similar to this:

    Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

    Step 3 - Checking the header

    You've already extracted the header now there are several things you need to do:

    1. Check that the header isn't null
    2. Check that the Authorization/Authentication mechanism is indeed "Basic"

    Like so:

    if (authHeader != null && authHeader.StartsWith("Basic")) {
        //Extract credentials
    } else {
        //Handle what happens if that isn't the case
        throw new Exception("The authorization header is either empty or isn't Basic.");
    }
    

    Now you have check that you are have something to extract data from.

    Step 4 - Extracting credentials

    Removing "Basic " Substring

    You can now attempt to get the values for username and password. Firstly you need to get rid of the "Basic " substring. You can do it like so:

    string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
    

    See the following links for further details:

    1. http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
    2. http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx

    Decoding Base64

    Now we need to decode back from Base64 to string:

    //the coding should be iso or you could use ASCII and UTF-8 decoder
    Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
    

    Now username and password will be in this format:

    username:password
    

    Splitting Username:Password

    In order to get username and password we can simply get the index of the ":"

    int seperatorIndex = usernamePassword.IndexOf(':');
    
    username = usernamePassword.Substring(0, seperatorIndex);
    password = usernamePassword.Substring(seperatorIndex + 1);
    

    Now you can use these data for testing.

    The Final Code

    The final code may look like this:

    HttpContext httpContext = HttpContext.Current;
    
    string authHeader = this.httpContext.Request.Headers["Authorization"];
    
    if (authHeader != null && authHeader.StartsWith("Basic")) {
        string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
        Encoding encoding = Encoding.GetEncoding("iso-8859-1");
        string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
    
        int seperatorIndex = usernamePassword.IndexOf(':');
    
        var username = usernamePassword.Substring(0, seperatorIndex);
        var password = usernamePassword.Substring(seperatorIndex + 1);
    } else {
        //Handle what happens if that isn't the case
        throw new Exception("The authorization header is either empty or isn't Basic.");
    }