Web API 2 OWIN Bearer Token purpose of cookie

asp.net-mvc-5asp.net-web-api2katanaowin

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?

Best Answer

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.

Related Topic