ASP.NET Core 3.1 JWT Cookie Authentication

JWT Authentication in ASP.NET Core 3.1 is very easy to implement with native support, which allows you to authorize endpoints without any extra dependencies. The middleware handles all the hard work, and all you have to do is add a few lines of code! However, there is one bit of documentation that may not be as obvious. How do you get the middleware to check the request cookies instead of the header?

Sometimes, when building a web app, you don’t want your client to handle the bearer token manually. It can be easier to persist information in a secure cookie. To take advantage of the existing .NET Core JWT middleware and use cookies, this simple trick will get you going on the right path.

(If you’re looking for information on how to set up JWT in your project, check out this tutorial.)

Inside your Startup.cs file, find where you registered the JWT authentication schema with the AddAuthentication method. The JWT bearer option AddJWTBearer(options) gives you the ability to access its Events. Add the following Event to your options:


options.Events = new JwtBearerEvents
{
  OnMessageReceived = context =>
  {
    context.Token = context.Request.Cookies["your-cookie"];
    return Task.CompletedTask;
  },
};

Now when the middleware receives a “message,” it will run the Event. This Event looks at the message’s cookies and sets the MessageReceivedContext Token to the cookie you specified. This will override the default, which would be pulling the token from the message’s headers.

Putting it all together, your AddAuthentication method should look something like this:


public void ConfigureServices(IServiceColleciton serivces)
{
  services.AddAuthentication(configureOptions =>
  {
    configureOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
  })
  .AddJwtBearer(options => 
  {
    options.TokenValidationParameters = new TokenValidationParameters
    {
      ValidateIssuerSigningKey = true,
      IssuerSigningKey = new SymmetricSecurityKey(key),
      ValidateIssuer = true,
      ValidIssuer = issuer,
      ValidateAudience = true,
      ValidAudience = audience,
      ValidateLifetime = true,
    };
    options.Events = new JwtBearerEvents
    {
      OnMessageReceived = context =>
      {
        context.Token = context.Request.Cookies["your-cookie"];
        return Task.CompletedTask;
      };
    }
  }
});

Now you can take full advantage of the .NET Core JWT middleware without being forced to use the request headers.

Conversation
  • Rahul says:

    Hi, surely this is short and sweet way to use cookies with JWT, thanks for sharing this.
    But I have a question, what if I generate JWT from separate .Net Core API project and still want to authenticate MVC layer as well using cookie, do we still need to provide TokenValidationParameters in MVC project or just options.Events would do the work?

    • Tiago Bernardo says:

      Hi! I make me the same question 😂😂😂😂! But i believe that token parameters depends of your application. In the example the author used a symmetric key for token, in my case i used Assymetric key then i not used token parameters. I coded like this:

      services.AddAuthentication(configureOptions =>
      {
      configureOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
      })
      .AddJwtBearer(x =>
      {
      x.RequireHttpsMetadata = true;
      x.SaveToken = true;
      x.SetJwksOptions(new JwkOptions(“http://myapi.com.br/jwks”));
      x.Events = new JwtBearerEvents
      {
      OnMessageReceived = context =>
      {
      context.Token = context.Request.Cookies[“AccessToken”];
      return Task.CompletedTask;
      }
      };
      });

      I hope that you undestand my english 😂😂😂😂😂😂😂😂😂😂😂
      Bye

      • Rahul says:

        Definitely, I understand that :)

        I have a question in mind and looking for answer for a long time.
        We Generate JWT token and refresh token from api and consume them on MVC application. Now, MVC application should be able to validate this token out of cookie (as seen in author’s code) but API should be validating that as received from header.
        When API reports that token is not valid then MVC regenerates it calling refresh token endpoint but how we can save new token respecting user’s remember me settings at time when he logged in?

  • J Bergman says:

    Can you provide an example of how you would set the cookie during authentication?

  • Rahut says:

    Hi,

    1. can you please show how to save JWT in cookie and based on Remember me setting on login form make that persistent or session based.

    2. How sliding expiration can be achieved with JWT returned from API?0

    3. How remember me = true can be used in subsequent token generation using refresh token as now user is not logging in manually, so how would you persist value for Remember me option and use for new tokens?

    Thanks

  • Bala says:

    Thanks a lot!! This saved lot of time :-)

  • Comments are closed.