JWT Authentication in C NET 5

Today in this article we will learn how to do JWT Authentication .NET Core with examples. We shall use .NET Core 3.1 or .NET6 applications with simple easy to understand examples.

We shall cover below aspects of enabling JWT authentication in ASP.NET Core API,

What is JWT

JSON Web Token( JWT) is an open standard used for securely transmitting information between parties as a JSON object. JSON Web Tokens are very useful for various scenarios like authorization purposes or Information exchange using digitally signed key-value pairs.

Below is a sample JWT token example,

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJleHAiOjE1NzEwMDc3MzQsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzQxIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDEifQ.
Ve2x6ueiHPyrP7wLjpmZrhx7QWrQKnkxWsu_1qUKKLA

Getting started

Create ASP.NET Core 3.1 or .NET 6 project,

Enable the JWT bearer Authentication scheme

Enabling JWT authentication in ASP.NET Core WebAPI is about registering the JWT Authentication middleware within the request pipeline.

Please note that the JWT middleware component was built into .NET Core 2.2 frameworks previously. But ASP.NET Core 3.1 onwards needs to be installed through the Nuget package separately.

Using Visual Studio

JWT Bearer Authentication in ASPNET Core C

OR

NuGet Package Manager CLI

PM>Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version <>

Note: Please use the latest available version

Now let’s see the step-by-step required for enabling the JWT bearer scheme. if you are interested in learning how to basic authentication in .NET core, please visit this article.

Please add below using namespaces to use the same in the code,

using Microsoft.IdentityModel.Tokens;

using Microsoft.AspNetCore.Authentication.JwtBearer;

In Startup.cs please update ConfigServices() method to register the JWT Authentication scheme.

Please use the AddAuthentication() extension methods for setting up authentication services in a ServiceCollection as below.

Here we have set DefaultAuthenticateScheme as JwtBearerDefaults.

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddCors();
          
            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            }).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["JwtToken:Issuer"],
                    ValidAudience = Configuration["JwtToken:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
                };
            });
        }

You may want to set up the configuration accordingly if supporting multiple authentication schemes in the same API.

TokenValidationParameters are explained as below. This is as per the MSDN details mentioned,

  • ValidateIssuerSigningKey – Gets or sets a boolean that controls if validation of the SecurityKey that signed the security token is called.

  • ValidIssuer – Gets or sets a String that represents a valid issuer that will be used to check against the token’s issuer.

  • ValidateIssuer – Gets or sets a value indicating whether the Issuer should be validated. True means, validation is required.

  • ValidAudience – Gets or sets a string that represents a valid audience that will be used to check against the token’s audience

  • ValidateAudience – Gets or sets a boolean to control if the audience will be validated during token validation.

  • ValidateLifetime – Gets or sets a boolean to control if the lifetime will be validated during token validation.

The following is the final implementation of the Configure() method.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors(option => option
               .AllowAnyOrigin()
               .AllowAnyMethod()
               .AllowAnyHeader());

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

In the above example, CORS will be needed only if your API needs to support cross-domain calls.

Authorize Method Attribute

The next step is to enable authentication using the [Authorize] attribute as below. 

[Authorize] attribute can also be applied at the Controller level (if you need to secure all methods within a Controller)

        [HttpGet]
        [Authorize] 
        public async Task<IEnumerable<string>> Get()
        {

            var accessToken = await HttpContext.GetTokenAsync("access_token");

            return new string[] { accessToken };
        }

Configure Secretes Key and Token

appsetting.json file has specified the values for the issuer, the audience, and the signing key, and these key-value pairs will be accessible through the Configuration in ASP.NET Core using Dependency Injection easily.

One can supply required values through an Environment variable or YAML or Secrete Storage if any (if the host environment is Cloud etc.)

The configuration file used in applications is shown below.

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "JwtToken": {
    "SecretKey": "xxxxxxxxxx...xx",
    "Issuer": "your issue address"
  }
}

Note

There is a limitation of the SecretKey length used in the SymmetricSecurityKey before signing and generating the signed credentials.

It’s recommended using a 128-bit key, generated with cryptographic algorithms as per RFC2104.

For .NET/.NET Core, the key Secret key should be a minimum of 128 bits i.e (16 bytes).

JWT secured Token

JWT token will be generated using a simple logic programmatically is already explained in the below article,

Let’s execute the API to validate the authentication and see if it is working fine.

.NET – Invoking a Secured method

Here I am using SOAP UI as a client to verify the token and invoke a secured GET method.

As shown below API response is 200 OK (successful).

We are reading the passed JWT token programmatically with a method.

JWT Bearer 200 OK (successful)

JWT Bearer 200 OK Postman

Above we are reading the JWT bearer token from a secured method using the “access_token” key.

The client should always send the Authorization header with the Bearer schema as below.

Authorization: Bearer <token>

Example :

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJleHAiOjE1NzEwMDc3MzQsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzQxIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDEifQ.Ve2x6ueiHPyrP7wLjpmZrhx7QWrQKnkxWsu_1qUKKLA

Let’s execute the API with an invalid token. You will start noticing Error 401: Unauthorized

 JWT Bearer Error 401: Unauthorized

For any invalid_token, API shall produce JWT Bearer Error 401: Unauthorized

JWT Authentication NET Core with example

Generate JWT bearer Token pro-grammatically

Please refer to the below few articles,

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!

Summary

Secured programming is not an afterthought process. It needs to be considered on the day first. Today in this article we understood how to use the JWT bearer token to secure ASP .NET Core applications in a few simple easy steps.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.