Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API 2 OWIN Bearer Token purpose of cookie?

I am trying to understand the new OWIN Bearer Token authentication process in the Single Page App template in MVC 5. Please correct me if I'm wrong, for the OAuth password client authentication flow, Bearer Token authentication works by checking the http authorization request header for the Bearer access token code to see if a request is authenticated, it doesn't rely on cookie to check if a particular request is authenticated.

According to this post:

OWIN Bearer Token Authentication with Web API Sample

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    using (IdentityManager identityManager = _identityManagerFactory.CreateStoreManager())
    {
        if (!await identityManager.Passwords.CheckPasswordAsync(context.UserName, context.Password))
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }

        string userId = await identityManager.Logins.GetUserIdForLocalLoginAsync(context.UserName);
        IEnumerable<Claim> claims = await GetClaimsAsync(identityManager, userId);
        ClaimsIdentity oAuthIdentity = CreateIdentity(identityManager, claims,
            context.Options.AuthenticationType);
        ClaimsIdentity cookiesIdentity = CreateIdentity(identityManager, claims,
            _cookieOptions.AuthenticationType);
        AuthenticationProperties properties = await CreatePropertiesAsync(identityManager, userId);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }
}

The GrantReourceOwnerCredentials function not only compose the ticket with this line: context.Validated(ticket); but it also compose a cookie identity and set it to the cookie with this line: context.Request.Context.Authentication.SignIn(cookiesIdentity);

So my questions are, what is the exact purpose of the cookie in this function? Shouldn't the AuthenticationTicket be good enough for authentication purpose?

like image 680
gavin Avatar asked Jan 04 '14 21:01

gavin


People also ask

What is bearer token in Web API?

Bearer token. A particular type of access token, with the property that anyone can use the token. In other words, a client doesn't need a cryptographic key or other secret to use a bearer token. For that reason, bearer tokens should only be used over a HTTPS, and should have relatively short expiration times.

How does token authentication work 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. This token contains enough data to identify a particular user and it has an expiry time.


2 Answers

In the SPA template there are actually two separate authentication mechanisms enabled- cookie authentication and token authentication. This enables authentication of both MVC and Web API controller actions, but requires some additional setup.

If you look in the WebApiConfig.Register method you'll see this line of code:

    config.SuppressDefaultHostAuthentication(); 

That tells Web API to ignore cookie authentication, which avoids a host of problems which are explained in the link you posted in your question:

"...the SPA template enables application cookie middleware as active mode as well in order to enable other scenarios like MVC authentication. So Web API will still be authenticated if the request has session cookie but without a bearer token. That’s probably not what you want as you would be venerable to CSRF attacks for your APIs. Another negative impact is that if request is unauthorized, both middleware components will apply challenges to it. The cookie middleware will alter the 401 response to a 302 to redirect to the login page. That is also not what you want in a Web API request."

So now with the call to config.SuppressDefaultHostAuthentication() Web API calls that require authorization will ignore the cookie that is automatically sent along with the request and look for an Authorization header that begins with "Bearer". MVC controllers will continue to use cookie authentication and are ignorant of the token authentication mechanism as it's not a very good fit for web page authentication to begin with.

like image 92
joelmdev Avatar answered Oct 11 '22 19:10

joelmdev


The existence of the cookie also left me puzzled, since it clearly is not necessary in a bearer token authentication scenario... In this post the author dissects the individual accounts template, and has the following to say about the cookie:

The method also sets an application cookie. I don’t see a good reason for that.

My guess is that the authors of the template wanted to show examples of different kinds of authentication logic, and in this particular case they wanted to show how the authentication information could be stored in both the bearer token authentication JSON payload, as well as in a standard authentication cookie.

The fact that the JSON authentication payload is set to also include an additional (unnecessary) unencrypted property (the user id), in addition to the encrypted ticket, seems to support this theory:

var properties = CreateProperties(user.UserName); var ticket = new AuthenticationTicket(oAuthIdentity, properties); 

It seems that the authors of the template wanted to provide some useful examples, rather than the bare minimum needed to achieve bearer token authentication. This is also mentioned in the linked post above.

like image 21
adner1 Avatar answered Oct 11 '22 21:10

adner1