Search code examples
c#asp.net-coreasp.net-identity

Update a claim in an ASP.NET Core 2.1 Authentication Cookie


How do I update a claim value in an ASP.NET Core 2.1 Authentication Cookie?

Little bit of context to my question:

I have an dotnet Core 2.1 MVC project that is using Cookie authentication.

The web site gets most of it's data from a API that uses bearer tokens to authenticate. The bearer tokens are fairly short lived and the API also returns a refresh token to get a new bearer token.

When the user logs in I get a token from the API and store it as a claim in the auth cookie, like so:

var props = new AuthenticationProperties{  ...  };

var claims = new[]
{
    new Claim("ApiAccessToken", apiToken.AccessToken),
    new Claim("ApiRefreshToken", apiToken.RefreshToken),
    // other claims ...
};

var identity = new ClaimsIdentity(claims, 
    CookieAuthenticationDefaults.AuthenticationScheme);

await Request.HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(identity), props);

I'm using Polly to ensure authentication before making calls to the API, if the first try to the API gets a 401, I use the refresh token to get a new bearer token. I want to update the ApiAccessToken and ApiRefreshToken claims in the auth cookie with these new values.


Or is there a altogether better way to handle this scenario?

Thanks.


Solution

  • I believe the answer to my question is "you don't".

    I ended up creating another cookie that holds the bearer token and the refresh token. I encrypted the refresh token for good measure.

    Example extension method code:

    public static void AppendApiAuthCookie(this HttpContext context, ApiAuthToken token, Guid userId)
    {
        context.Response.Cookies.Append("mytoken", $"bearerToken:{token.BearerToken}|refreshtoken:{token.RefreshToken}|uid:{userId}", 
         new CookieOptions
         {
            HttpOnly = true,
            SameSite = SameSiteMode.Strict,
            Expires = DateTimeOffset.UtcNow.AddHours(24),
         });
    }
    

    I then delete the cookie on sign out.

    Note (and this may be stating the obvious): That in my scenario, using Polly to ensure authentication, the Polly policy handler goes and gets a new token from the auth provider and updates the cookie. The new value you've just stored in the cookie isn't available from the cookie in the current request context. So you need to make sure that you're holding the new bearer token somewhere for the life of the request so you can grab it in the current request context.