0 Comments

When working with the new Identity 2.0 and WebAPI Owin Authentication there is a specific flow you have to follow in order to query an endpoint that need authorization (marked with [Authorize] attribute). Let get going:

First we’ll start with a new ASP.NET project and choose the WebAPI template, make sure that the Authentication is Individual User Account, this will setup the project with all the basic configuration to easily and rapidly use the new Identity provider.

If we look in the Startup.Auth.cs class we can see many of the setup for the Individual User account. What is interesting to us is in this part of the code:

// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    AllowInsecureHttp = true
};

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
Our application will be using Bearer Token as the auth mechanism…this will be important later on, also notice where the token endpoint is “/Token”.

Right now if we we’re to try and call a secured endpoint(/api/values) we would get a a 401 Unauthorized, because the route is marked with the Authorize Attribute. In order for us to call this endpoint we must be:

  1. A registered user
  2. User must be Authorized (by internal or external providers) In a new project there is no existing user (unless you are hooking up to an existing Database that supports the Identity Model), just for transparency I called the endpoint to register a user :
    POST /api/account/register
    {"email":"mat1@matrichard.com",
    "password": "!a12345A",
    "confirmPassword": "!a12345A"}
    

     

    The password validation settings are configured in the IdentityConfig.cs class and these are the default configs:

    manager.PasswordValidator = new PasswordValidator
    {
        RequiredLength = 6,
        RequireNonLetterOrDigit = true,
        RequireDigit = true,
        RequireLowercase = true,
        RequireUppercase = true,
    };
    

     

    Let’s get back to what is at heart …how to call that /api/values and get a 200 OK instead of 401 Unauthorized. Since I now have a registered user, I only need to Authorize this user, this will be done by making an API call to /Token like so:

    POST /token
    username=mat1%40matrichard.com&password=!a12345A&grant_type=password
    

    Two very important things to note with /token :

    1. The Content-Type MUST be application/x-www-form-urlencoded
    2. A grant_type with the value password MUST be supplied in the body

     

    If everything goes as planned we should receive a 200 OK response with a body that looks very close to that (I removed the access_token for readability purpose) :

    {"access_token":"[A VERY VERY BIG VALUE]",
    "token_type":"bearer",
    "expires_in":1209599,
    "userName":"mat1@matrichard.com",
    ".issued":"Wed, 19 Nov 2014 02:40:33 GMT",
    ".expires":"Wed, 03 Dec 2014 02:40:33 GMT"}
     

    So now based on this response we can build our call to /api/values by simply adding the token value in the authorize header and pre-pending it with the token_type like so :

    Authorization: Bearer [INSERT TOKEN VALUE]
    

     

    It’s that simple.

    Mat
    @matrichard5