Implement JWT Authentication in Asp.net Core 5 Web API [Token Base Auth]

/ / 13 Comments

Asp.net Core JWT token Authentication: Here in this article we learn a complete step-by-step process to implement Authentication in Asp.net Core Web API using JSON Web Token ie JWT. We must ensure that our APIs are protected and secure when developing them.

That is, we need to authenticate a user so that only valid users can consume our APIS. Using JWT we can easily implement Token Based Authentication in Asp.net Core and safeguard our application. Also check once access token is expired how to implement JWT refresh token in Asp.net Core application

What is JSON Web Token?

The RFC 7519 JSON Web Token (JWT) is an open, industry-standard technique for securely conveying claims between two parties. This means that data sent between two parties using JWT is digitally signed and can be easily confirmed and trusted.

In short, using JWT we can implement Authentication and Authorization in any Web Application with any backend stack i.e Asp.net Core, Java, NodeJs, Python, etc... 

Steps to Implement JWT Authentication in Asp.net Core

  • Understanding JWT Authentication Workflow.
  • Create Asp.net Core Web API project
  • Install NuGet Package (JwtBearer)
  • Asp.net Core JWT appsetting.json configuration
  • Asp.net Core Startup.cs - configure services add JwtBearer
  • Create Models User, Tokens
  • Create JWTManagerRepository to Authenticate users and generate JSON Web Token.
  • Create UserController - Authenticate action method.

# Understanding JWT Authentication Workflow.

Here in the below image, we illustrate the JWT Authentication flow diagram in Asp.net Core Web API.



# Create Asp.net Core Web API project

Here first we create the Asp.net Core web API project am using Asp.net Core 5 version if you want you can also select a lower version i.e Asp.net Core 3.1 version.

# Install NuGet Package (JwtBearer)

As Asp.net Core 5 Web API project is created successfully, so now we installed some NuGet packages using Visual Studio Nuget Package Manager UI i.e Tools --> NuGet Package Manager --> Manage NuGet Packages for Solution

The 2 NuGet packages which we need to implement JWT authentication in the Asp.net Core application are Microsoft.AspNetCore.Authentication.JwtBearer and System.IdentityModel.Tokens.Jwt.

# Asp.net Core JWT appsetting.json configuration

After the NuGet packages are installed, next we modify our appsetting.json file and add secret key and other values. These values we needed further while generating JSON Web Token.

Our appsetting.json file looks similar to as written below:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "JWT": {
    "Key": "This is my supper secret key for jwt",
    "Issuer": "https://codepedia.info",
    "Audience": "codepedia.info"
  }
}

Here we added JWT new root element and it has 3 values i.e Key, Issuer, Audience.

# Asp.net Core Startup.cs - Configure services add JwtBearer

In Asp.net Core application Startup.cs file is the entry point of the application. It allows us to load configuration, register dependencies services and set the ordering of the request pipeline.

In Configure method we add UseAuthentication() middleware before UseAuthorization() middleware. Also in ConfigureServices method we configuration AddAuthentication with AddJwtBearer.

Our Startup.cs file code look like as written below:

public void ConfigureServices(IServiceCollection services)
{
	services.AddAuthentication(x =>
	{
		x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
		x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
	}).AddJwtBearer(o =>
	{
		var Key = Encoding.UTF8.GetBytes(Configuration["JWT:Key"]);
		o.SaveToken = true;
		o.TokenValidationParameters = new TokenValidationParameters
		{
			ValidateIssuer = false,
			ValidateAudience = false,
			ValidateLifetime = true,
			ValidateIssuerSigningKey = true,
			ValidIssuer = Configuration["JWT:Issuer"],
			ValidAudience = Configuration["JWT:Audience"],
			IssuerSigningKey = new SymmetricSecurityKey(Key)
		};
	});

	services.AddSingleton<IJWTManagerRepository, JWTManagerRepository>();

	services.AddControllers();
}

Here using Configuration["JWT:Key"] we get the secret key from our appsetting.json file.


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

	app.UseHttpsRedirection();
	app.UseRouting();

	app.UseAuthentication(); // This need to be added	
	app.UseAuthorization();
	app.UseEndpoints(endpoints =>
	{
	    endpoints.MapControllers();
	});
}

Note: In the Startup.cs file we need to import 2 namespaces i.e Microsoft.IdentityModel.Tokens and Microsoft.AspNetCore.Authentication.JwtBearer.

# Create Models Users, Tokens

Now we add a new folder named Models and add two new classes .i.e Users, Token. Our both classes file codes look like as written below.

Users.cs file code:

public class Users
{
	public string Name { get; set; }
	public string Password { get; set; }
}

User class has two properties i.e Name, and Password. We use this class in our usercontroller action method for authenticating.

Tokens.cs file code:

public class Tokens
{
	public string Token { get; set; }
	public string RefreshToken { get; set; }
}	

Tokens class has two string properties i.e Token, and RefreshToken.

Once the user is authenticated successfully, we generate a JWT token and return it to this Tokens class object.

# Create an IJWTManagerRepository interface to Authenticate users and generate JSON Web Token.

Now we create a new folder named Repository, under which create a new interface as IJWTManagerRepository.

In the interface IJWTManagerRepository we add a method Authenticate(Users u), which returns a valid JWT Token. Our IJWTManagerRepository.cs file code look like as written below:

using JWTWebAuthentication.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace JWTWebAuthentication.Repository
{
   public interface IJWTManagerRepository
    {
        Tokens Authenticate(Users users); 
    }
   
}

Next we create a new class file named as JWTManagerRepository.cs and inherit the interface IJWTManagerRepository.

Here we add Dictionary as UsersRecords, which contains our user record. You can do this with a database, as our primary focus is to implement JWT so am using a dictionary with dummy records.

Our final code to look like at written below:

public class JWTManagerRepository : IJWTManagerRepository
{
	Dictionary<string, string> UsersRecords = new Dictionary<string, string>
	{
		{ "user1","password1"},
		{ "user2","password2"},
		{ "user3","password3"},
	};

	private readonly IConfiguration iconfiguration;
	public JWTManagerRepository(IConfiguration iconfiguration)
	{
		this.iconfiguration = iconfiguration;
	}
	public Tokens Authenticate(Users users)
	{
		if (!UsersRecords.Any(x => x.Key == users.Name && x.Value == users.Password)) {
			return null;
		}

		// Else we generate JSON Web Token
		var tokenHandler = new JwtSecurityTokenHandler();
		var tokenKey = Encoding.UTF8.GetBytes(iconfiguration["JWT:Key"]);
		var tokenDescriptor = new SecurityTokenDescriptor
		{
		  Subject = new ClaimsIdentity(new Claim[]
		  {
			 new Claim(ClaimTypes.Name, users.Name)                    
		  }),
		   Expires = DateTime.UtcNow.AddMinutes(10),
		   SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey),SecurityAlgorithms.HmacSha256Signature)
		};
		var token = tokenHandler.CreateToken(tokenDescriptor);
		return new Tokens { Token = tokenHandler.WriteToken(token) };

	}
}

Here first we check if the user is valid or not. If the user is not valid, then we return null, else we generate JSON Web Token and return the Tokens class object.  

When using a JWT token, authorizations are based on the claims contained in the JWT token.

To set JWT token expiration time in Asp.net Core , we use the Expires parameter of SecurityTokenDescriptor, and set its value as whatever we want. We can use .AddMinutes() to set JWT token expire in minutes, or .AddHours() to set JWT token expire in hours.

Here in the above code we set the JWT token expiration time as 10 mins, hence after 10 mins the token gets invalid.

Note: We need to register IJWTManagerRepository service in our Startup.cs ConfigureServices method.

#Create UserController - Authenticate action method 

In the Controllers folder, we add a new controller named as UsersController and in its constructor we inject IJWTManagerRepository interface.

The UsersController has two Action methods one for authenticating the user and in response getting JSON Web Token (JWT). And another to display the list of users only if the user is authenticated by using JWT. 

Our UsersController code look like as written below:

[Authorize]
[Route("api/[controller]")]
[ApiController]  
public class UsersController : ControllerBase
{
	private readonly IJWTManagerRepository _jWTManager;

	public UsersController(IJWTManagerRepository jWTManager)
	{
		this._jWTManager = jWTManager;
	}

	[HttpGet]
	public List<string> Get()
	{
		var users = new List<string>
		{
			"Satinder Singh",
			"Amit Sarna",
			"Davin Jon"
		};

		return users;
	}

	[AllowAnonymous]
	[HttpPost]
	[Route("authenticate")]
	public IActionResult Authenticate(Users usersdata)
	{
		var token = _jWTManager.Authenticate(usersdata);

		if (token == null)
		{
			return Unauthorized();
		}

		return Ok(token);
	}
}

Here, at controller level we decorated with [Authorize] attribute, to ensure that no action methods are invoked without authentication.

Similarly, at the Authenticate IAction method, we decorated it with [AllowAnonymous] attribute, which overrides the [Authorize] attribute. This allows all users to access the Authenticate IAction method, which returns JWT if the user is legitimate.

The [Authorize] attribute is responsible of validating the token against the rules defined in Startup.cs ConfigureServices method.

Lets consume these API from Postman.

First we call Get request, to check whether we able to display users records, without any authentication.

As in Fig 1 in response is returns as 401 Unauthorized

Fig1: 

Next now we call authenticate API with valid user credentials. As in Fig 2 in response we got JWT Token, which we used in header for authentication.

Fig2:


Now we again call the Get method, but with valid token, which we generated in previous call. As in Fig 3 we able to display user data, after proper authentication using JSON Web Token.

Fig 3:


Conclusion: Using JWT we successfully implement Token Base Authentication in Asp.net Core Web API. And with this, we were able to secure our WebAPI in Asp.net Core using JWT.

Other Reference:

Thank you for reading, pls keep visiting this blog and share this in your network. Also, I would love to hear your opinions down in the comments.

PS: If you found this content valuable and want to thank me? 👳 Buy Me a Coffee

Subscribe to our newsletter

Get the latest and greatest from Codepedia delivered straight to your inbox.


Post Comment

Your email address will not be published. Required fields are marked *

13 Comments

  1. Gael BK 05/06/2022 12:32:11
    Very good tutorial thank you for the effort.
  2. sourbh 05/24/2022 03:25:50
    where you are validating your token after it is created in get call
  3. Isaac 05/29/2022 20:55:57
    Thank you so much for this beautiful and clear tutorial. I have successfully implemented API security using this (JWT Authentication) and it works perfectly
  4. FrankW 06/18/2022 09:37:21
    Thanks for this beautiful tutorial. I have a problem: ValidateLifetime = true do not works! Can anyone helps? Frank
  5. Satinder singh 06/18/2022 11:41:14
    Hi Frank, Can you elaborate more what issue you face by setting ValidateLifetime = true
  6. Rustam 06/25/2022 02:14:19
    This article very helpful thank's author
  7. Kenia 07/04/2022 08:15:56
    Thanks for a good and explicit tutorial! Cheers
  8. Obadiah 07/04/2022 16:16:57
    This tutorial is wow!!! very straight and definite , i enjoyed it. please is there any article on creating API keys that i can read too?
  9. Ajay 07/13/2022 18:30:46
    Very crisp and clear article,Thanks But I have one query where we you have validated the generated token.
  10. Satinder Singh 07/14/2022 09:23:58
    Hi Ajay, Thanks for reading, glad you found it helpful. And answer to your question about API authentication we decorate our controller with [Authorize] attibute and by using [AllowAnonymous] we make it accessible for everyone.
  11. Tegar Swasono 10/14/2022 01:57:21
    thanks bro, very good tutorial.
  12. Eusebio Z 11/18/2022 17:50:26
    Thank you very much for the tutorial, one question, can I [Authorize] this generated token in another Asp.net Core Web API project? How could it be done? Thank you very much in advance
  13. Satinder Singh 11/20/2022 16:01:25
    Hi Eusebio , Yes this is the standard way to implement jwt in any Asp.net Core. So you can copy paste this code in any asp.net core application