Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Web API access tokens validated on the server?

Once a WebAPI access token is generated, how does WebAPI validate that token for the next request? I wonder if I can use an [Authorize] attribute, it must compare the token sent by the client with the token at the server side, if stored somewhere. Does it just check if token is present and not its value?

like image 633
Mohan Sharma Avatar asked May 29 '16 07:05

Mohan Sharma


People also ask

How does Web API validate token?

What is Token Based Authentication in Web API? Token-based authentication is a process where the client application first sends a request to Authentication server with a valid credentials. The Authentication server sends an Access token to the client as a response.

How is access token validated by resource server?

The access token A resource server validates such a token by making a call to the authorisation server's introspection endpoint. The token encodes the entire authorisation in itself and is cryptographically protected against tampering. JSON Web Token (JWT) has become the defacto standard for self-contained tokens.

How are tokens validated?

You can validate your tokens locally by parsing the token, verifying the token signature, and validating the claims that are stored in the token. Parse the tokens. The JSON Web Token (JWT) is a standard way of securely passing information. It consists of three main parts: Header, Payload, and Signature.


2 Answers

Bearer token

First of all, your Identity Provider or Token Provider which issues the authorization tokens needs to have the same machine key settings as the Web Api application for encryption/decryption:

<machineKey decryptionKey="B7EFF1C5839A624ED0268917EDE82F408D2ECBFAC817" validation="SHA1" validationKey="C2B8DF31AB9624D8066DFDA1A479542825F3B48865C4E47AF6A026F22D853DEC2B3248DF268599BF89EF78B9E86CA05AC73577E0D5A14C45E0267588850B" /> </system.web>

Because under the hood Bearertoken uses MachineKey encryption. In other words if you dont have the same settings, your web api won't be able to decrypt the token (validate it). This is done automatically by:

Microsoft.Owin.Security.OAuth.dll

using middleware.

You can use the Authorize Attribute on your web api controllers/actions if you want simple authorization with Usernames or roles like this:

[Authorize(Roles="Administrators,Managers",Users ="Mike,Laura")] 

If you want custom authorization, then you have to implement a custom authorization attribute which will handle the custom authorization in your web api. If the user is not allowed to pass you will return a 401 UnAuthorized Response:

actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
actionContext.Response.Headers.Add("WWW-Authenticate","Bearer location='http://localhost:8323/account/login'");

For example:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class CustomAuthorizeAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
    public RulesExampleEnum[] Rules { get; set; }
    public string Id { get; set; }
    .....
// Summary:
//     Calls when a process requests authorization.
//
// Parameters:
//   actionContext:
//     The action context, which encapsulates information for using System.Web.Http.Filters.AuthorizationFilterAttribute.
public virtual void OnAuthorization(HttpActionContext actionContext);
public virtual Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken);

and register it in your webApiConfig.cs

config.Filters.Add(new CustomAuthorizeAttribute());

and apply it on Web Api controller or action:

[CustomAuthorize(Id = "AnyId", Rules = new RulesExampleEnum[] { RulesExampleEnum.Rule1, RulesExampleEnum.Rule3 })]
public IEnumerable<object> Get()
{...
like image 141
Legends Avatar answered Oct 23 '22 15:10

Legends


Once access token is generated, client must include the access token inside Header for each request.

Client may set the access token inside Authorization HTTP Header.

On the server side, you should create class to handle the Authorization, which is a derived class from System.Web.Http.AuthorizeAttribute, something like below :

public class AuthorizationHandlerAttribute : AuthorizeAttribute
{
    string AccessTokenFromRequest = "";
    if (actionContext.Request.Headers.Authorization != null)
    {
        // get the access token
        AccessTokenFromRequest = actionContext.Request.Headers.Authorization.Parameter;
    }

    string AccessTokenStored = ""; 
    // write some code to get stored access token, probably from database 
    // then assign the value to a variable for later use

    // compare access token
    if (AccessTokenFromRequest != AccessTokenStored)
    {
        // if the token is not valid then return 401 Http Stasus
        // or simply call base method 
        base.HandleUnauthorizedRequest(actionContext);
    }
}

Then you use the newly created class and attach it on controller or action you wished to protect from unauthorized access.

public class UsersController : ApiController
{
    [AuthorizationHandler]
    public User Get(int id)
    {
        // only request with valid access token will reach this 
    }
}
like image 39
Michael Avatar answered Oct 23 '22 15:10

Michael