Application authentication
.NET Core ASP.NET Core Identity C# JWT OAuth Top Visual Studio

Persisting JWT Tokens in a .NET Core Application

Welcome to today’s post.

In this post I will be showing how to persist and reuse JWT tokens within an ASP.Net Core web application.

In earlier posts I showed the following:

  1. How to create a JWT identity server.
  2. How to register and authenticate accounts using an existing JWT identity server.
  3. Decoding and validate JWT tokens to retrieve user claims.

Before the JWT token can be used within a web client, the authentication middleware for JWT bearer tokens has to be enabled within the startup ConfigureServices():

// jwt token authentication
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(
   options =>
   {
      options.Authority = "https://localhost/BookLoan.Identity.API/";
      options.Audience = "https://localhost/";
   }); 

This establishes what the authority is that provides our JWT tokens.

The following code shows how to authenticate a user, retrieve the JWT token and store the token in a cookie:

public async Task<IActionResult> Authenticate([FromBody] UserViewModel userDto)
{
     var request = new HttpRequestMessage(HttpMethod.Post,                   "http://localhost/BookLoan.Identity.API/api/Users/Authenticate");

     var client = _clientFactory.CreateClient();

     var content = JsonConvert.SerializeObject(userDto);

     StringContent stringContent =
        new StringContent(content, System.Text.Encoding.UTF8,
           "application/json");

     var response = await client.PostAsync(request.RequestUri,
        stringContent);

     string token = "";

     if (response.IsSuccessStatusCode)
     {
        string respContent =  response.Content.ReadAsStringAsync().Result;

        AuthenticationResponseViewModel aitem = JsonConvert.DeserializeObject<AuthenticationResponseViewModel>(respContent);
        token = aitem.Token;

        ClaimsPrincipal principal =_tokenManager.GetPrincipal(token);

        _context.User = principal;

        var option = new CookieOptions();
        option.Expires = DateTime.Now.AddMinutes(30);
        if (_context.Request.Cookies["token"] == null)
           _context.Response.Cookies.Append("token", token, option);
                
        return new OkResult();
     }

     return new UnauthorizedResult();
}

Retrieving claim details from a token is done as follows:

string name = "";
if (_context.Request.Cookies["token"] != null)
{
   string token = _context.Request.Cookies["token"]; 
   if (token.Length > 0)
   {
       ClaimsPrincipal claimsPrincipal =
          _tokenManager.GetPrincipal(token);
       foreach (Claim claim in claimsPrincipal.Claims)
       {
          if (claim.Type == ClaimTypes.Name)
          {
             name = claim.Value;
          }
       }
   }
}

If the claims contains roles, they can also be retrieved and used for authorization. This will be shown in a future post.

To use httpContext and httpClient in .NET Core applications the following are recommended (as I showed in previous posts):

  1. Inject IHttpContextAccessor into your service or controller that is using the web request http context. 
  2. Inject IHttpClientFactory into your service or controller that is using the http client for GET and POST requests over HTTP

Note: As we are bypassing the OWIN authentication that ASP.NET Identity uses for signing in, signing out and authentication, we have had to persist the authentication token and provide the remaining authentication functions in our own web API.

I will show in a future post how to combine authorization handlers and JWT declarative authorization of controller methods.

That’s all for today’s post.

I hope this post has been useful and informative.

Social media & sharing icons powered by UltimatelySocial