Web API Security: Basic Authentication with Thinktecture.IdentityModel AuthenticationHandler

In my last post, I showed how to configure the AuthenticationHandler using the AddMapping method. While you have full control here, I added a number of convenience extension methods that cover common use case. Following is an overview of the HTTP Basic Authentication related extensions.

Simple
The following code is the simplest way to setup Basic Authentication:

  • Credential is expected on the Authorization header using a scheme of Basic
  • Validation is done by the default membership provider
  • Www-Authenticate header with scheme of Basic and a realm of localhost get sent back with the 401
var config = new AuthenticationConfiguration
{
    RequireSsl = true
};
            
// delegate validation to membership provider
config.AddBasicAuthentication(Membership.ValidateUser);

 

In addition you can pull roles from the default role provider like this (or any other method with the same signature):

// delegate validation to membership and fetch roles from role manager
config.AddBasicAuthentication(
    Membership.ValidateUser, 
    Roles.GetRolesForUser);

 

Custom credential validation
You can use whatever logic you like to validate the credentials. As long as your method takes two strings (user name and password) and returns a bool (success or not).

// custom username validator
config.AddBasicAuthentication(ValidateUser);

 

When credential validation fails, a 401 status code gets sent back. You can control the exact layout of the response by throwing an AuthenticationException inside the credential validation logic. The following code shows how to send back a 400 (bad request) instead of a 401 (sample code!):

private static bool ValidateUser(string userName, string password)
{
    if (userName == "bob")
    {
        throw new AuthenticationException
        {
            StatusCode = HttpStatusCode.BadRequest,
            ReasonPhrase = "Invalid client"
        };
    }
 
    return true;

}

Retain password
Sometimes you want to defer validation of credentials, or need the client password for delegation. In that case you can use the retain password option to save the password as a password claim that you can access later from the claims collection:

// retain password
config.AddBasicAuthentication(ValidateUser, retainPassword: true);
 

Custom realm and headers
You can also specify a realm for the response header:

// different realm

config.AddBasicAuthentication(ValidateUser, “MyRealm”);

…and to look for credentials on a different header:

// different header
config.AddBasicAuthentication(
    ValidateUser, 
    AuthenticationOptions.ForHeader("X-Authorization"), 

    “My Realm”);

 

Claims Transformation
If you need more control over the returned claims, you can specify a ClaimsAuthenticationManager derived implementation on AuthenticationConfiguration.

You can of course also create new extension methods over the raw AddMapping functionality if something you frequently need is missing.

HTH

This entry was posted in IdentityModel, WebAPI. Bookmark the permalink.

58 Responses to Web API Security: Basic Authentication with Thinktecture.IdentityModel AuthenticationHandler