JWT Token Authentication In ASP.NET Core 6 Web API Using Three Tier Architecture

Introduction

In this article, we will implement the JWT Token based Authentication using asp.net Core 6 by following the 3-tier architecture. If you want to learn 3-tier architecture, then click the below link.

JSON Web Token is an open standard that allows transmitting the data between parties as JSON is digitally signed, so the information is trusted and verified. JWT Token can be signed using secret (with HMAC) Algorithm or with the public or private key pairs using RSA Or ECDSA. JWT Token Authentication is very popular in Website Development.

Implementation of JSON Web Token in Asp.Net Core 6 Web API

First, Create the project of Asp.net Core Web API using the API Template given in Visual Studio or Visual Studio Code using CLI

  • Dotnet new WebAPI -n JwtTokenAuthentication

Create the Project For Presentation Layer

Paste this command in the CLI and hit enter, CLI will create the Web API Template

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Select the Name of your project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Select .Net 6

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

And then click the Create button, Visual Studio will create the template for us

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Our Web API Template has been created. Install the following packages in the web API Template

  1. Microsoft.AspNetCore.Authentication.JwtBearer
  2. Microsoft.EntityFrameworkCore
  3. Microsoft.EntityFrameworkCore.Design
  4. Microsoft.EntityFrameworkCore.SqlServer
  5. Microsoft.EntityFrameworkCore.Tools
  6. Microsoft.IdentityModel.JsonWebTokens
  7. System.IdentityModel.Tokens.Jwt

And we have discussed above that in this project we will use the three-tier architecture so our second step will be to create the layer in this project. Now we will add the Data Access layer to the project. For this, we will use the asp.net core library project.

Create the project for Data Access Layer

Click on your solution folder and then click on Add Button. I have already created all the projects but for the article, I will repeat all the steps.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Click on Add -> New Project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Select the Class Library Project and click on Next

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

After Clicking Next Select the Name of your project. As we know that this project is for Data access layer so our Convention of this project will be Name of Parent Project _ DAL. After giving the name hit the create button, visual studios will create the Class Library project using the support of Asp.net core 6.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Click Next and select the .net 6 Support

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Then hit the Create Button and Visual Studio Will create the Class Library Project for using and now you can see that our Class Library project has been created.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Now we will create the Business access layer project. For this repeat the above process that we have learned for creating the data access layer.

Create the project for Business Access Layer

Write Click on your Solution and then click on Add

Add->New Project->Select the Class Library Project -> Name of the Project -> Next-> Select the Net Core 6 -> Create

After following the steps, we have now our business access layer project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Add the Reference of Projects

 In this step, we need to add project references in the respective projects

Add the References of DAL and BAL in Presentation Layer

Select your API Project and right click on the project and click the Add button and click on project Reference for Presentation Layer. We need references of both data access layer and business access layer

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Select both project and click Ok

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Now you can see that the project references have been added to our project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Add the Data Access Layer References in Business access layer

Right Click on the Business Access layer project and click on Add and select the project references and in this layer we need only data access layer reference.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Select the DAL Project and Click on Ok Button

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Now you can see that our Data Access layer (DAL) project references have been added to our business access layer (BAL) project.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Implementation of JSON Web Token in Our Code

For implementation, we will first complete the Data Access layer and then Business access layer and finally we will complete Presentation Layer

Data Access Layer

First, install the following Nuget Packages in the project.

  • Microsoft.AspNetCore.Identity.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools

In Data Access layer Create the flowing Folders

  • Contracts
  • Data
  • Model
  • Repository

Migration folder will be automatically added when we do migration

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Contracts

In contracts, we define the interface for the project. In this project we will create the Generic Interface like Code is given below

Create the IRepository Generic Interface Class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Contracts {
    public interface IRepository < T > {
        public Task < T > Create(T _object);
        public void Delete(T _object);
        public void Update(T _object);
        public IEnumerable < T > GetAll();
        public T GetById(int Id);
    }
}

Models

Create the Model class for AppUser and extends this class from Identity User Class IdentityUser

using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Models {
    public class AppUser: IdentityUser {
        public int Id {
            get;
            set;
        }
        public string ? Name {
            get;
            set;
        }
        public string ? AccountType {
            get;
            set;
        }
        public string ? PhoneNo {
            get;
            set;
        }
        public string ? Password {
            get;
            set;
        }
        public string ? ShopName {
            get;
            set;
        }
        public string ? BusinessType {
            get;
            set;
        }
        public string ? UserRole {
            get;
            set;
        }
        public bool ? IsDeleted {
            get;
            set;
        }
    }
}

Data

In Data folder we create the application db.context class which is a very important class for creating Migration and Communication with database. We create the dbcontext class and extend that class from IdentityDbContext and pass our app user model class.

using JWTTokenAuthInAspNet6_DAL.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Data {
    public class AppDbContext: IdentityDbContext < AppUser > {
        public AppDbContext(DbContextOptions < AppDbContext > options): base(options) {}
        protected override void OnModelCreating(ModelBuilder builder) {
            base.OnModelCreating(builder);
        }
        public DbSet < AppUser > AppUsers {
            get;
            set;
        }
    }
}

Add the Db Set property in the application db Context Class for our app user Class

public DbSet<AppUser> AppUsers { get; set; }

Migrations

Now we will Create the Migration

Open the project Manager Console and select the Data Access Layer Project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Write the Following Commands

  • add-migration JSONWebTokenM1

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Then Update the database

  • update-database

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Now we have the Migration Folder in our project

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

We have created the Migrations and updated the database

Repository

In the Repository we will write all the database access Methods for Create, Delete and Update and View the data

Create the Repository Class and Extends the IRepository Interface and implements the interface. Here we need the references of Db Context Class. Using that class we will implement all the CRUD methods in the Repository

Remember that our interface is generic and when we extends the

using JWTTokenAuthInAspNet6_DAL.Contracts;
using JWTTokenAuthInAspNet6_DAL.Data;
using JWTTokenAuthInAspNet6_DAL.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_DAL.Repositories {
    public class RepositoryAppUser: IRepository < AppUser > {
        private readonly AppDbContext _appDbContext;
        private readonly ILogger _logger;
        public RepositoryAppUser(ILogger < AppUser > logger) {
            _logger = logger;
        }
        public async Task < AppUser > Create(AppUser appuser) {
            try {
                if (appuser != null) {
                    var obj = _appDbContext.Add < AppUser > (appuser);
                    await _appDbContext.SaveChangesAsync();
                    return obj.Entity;
                } else {
                    return null;
                }
            } catch (Exception) {
                throw;
            }
        }
        public void Delete(AppUser appuser) {
            try {
                if (appuser != null) {
                    var obj = _appDbContext.Remove(appuser);
                    if (obj != null) {
                        _appDbContext.SaveChangesAsync();
                    }
                }
            } catch (Exception) {
                throw;
            }
        }
        public IEnumerable < AppUser > GetAll() {
            try {
                var obj = _appDbContext.AppUsers.ToList();
                if (obj != null) return obj;
                else return null;
            } catch (Exception) {
                throw;
            }
        }
        public AppUser GetById(int Id) {
            try {
                if (Id != null) {
                    var Obj = _appDbContext.AppUsers.FirstOrDefault(x => x.Id == Id);
                    if (Obj != null) return Obj;
                    else return null;
                } else {
                    return null;
                }
            } catch (Exception) {
                throw;
            }
        }
        public void Update(AppUser appuser) {
            try {
                if (appuser != null) {
                    var obj = _appDbContext.Update(appuser);
                    if (obj != null) _appDbContext.SaveChanges();
                }
            } catch (Exception) {
                throw;
            }
        }
    }
}

Business Access layer

In the business access layer, we write the services of our project in this project our structure will be like.

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Here we have the services that implement the CRUD Logic of all the Repositories. In the services folder we create the AppUserServices Service class and here we will use the Repository for implementing the CRUD operations.

using JWTTokenAuthInAspNet6_DAL.Contracts;
using JWTTokenAuthInAspNet6_DAL.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JWTTokenAuthInAspNet6_BAL.Services {
    public class ServiceAppUser {
        public readonly IRepository < AppUser > _repository;
        public ServiceAppUser(IRepository < AppUser > repository) {
            _repository = repository;
        }
        //Create Method 
        public async Task < AppUser > AddUser(AppUser appUser) {
            try {
                if (appUser == null) {
                    throw new ArgumentNullException(nameof(appUser));
                } else {
                    return await _repository.Create(appUser);
                }
            } catch (Exception) {
                throw;
            }
        }
        public void DeleteUser(int Id) {
            try {
                if (Id != 0) {
                    var obj = _repository.GetAll().Where(x => x.Id == Id).FirstOrDefault();
                    _repository.Delete(obj);
                }
            } catch (Exception) {
                throw;
            }
        }
        public void UpdateUser(int Id) {
            try {
                if (Id != 0) {
                    var obj = _repository.GetAll().Where(x => x.Id == Id).FirstOrDefault();
                    if (obj != null) _repository.Update(obj);
                }
            } catch (Exception) {
                throw;
            }
        }
        public IEnumerable < AppUser > GetAllUser() {
            try {
                return _repository.GetAll().ToList();
            } catch (Exception) {
                throw;
            }
        }
    }
}

Presentation Layer

In our presentation layer our project structure will be like

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

In the Presentation layer we need the Following Packages for Implementation of JWT Auth and Entity Framework Operations

Microsoft.AspNetCore.Authentication.JwtBearer
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.IdentityModel.JsonWebTokens
System.IdentityModel.Tokens.Jwt

Common Folder

In Common folder we create the classes that are commonly used in our application for this project. We create the API Response class that contains only two properties Status and Message.

namespace JWTTokenAuthInAspNet6.Commons
{
    public class Response
    {
        public string? Status { get; set; }
        public string? Message { get; set; }
    }
}

View Model

In View Model we have two View Model Classes like

  • Register View Model
  • Sign In View Model

Sign In View Model

namespace JWTTokenAuthInAspNet6.ViewModels {
    public class LoginVM {
        //public string? Id { get; set;}
        public string ? UserName {
            get;
            set;
        }
        public string ? Password {
            get;
            set;
        }
    }
}

Register View Model

using Microsoft.AspNetCore.Identity;
namespace JWTTokenAuthInAspNet6.ViewModels {
    public class RegisterVM {
        public string ? Name {
            get;
            set;
        }
        public string ? AccountType {
            get;
            set;
        }
        public string ? PhoneNo {
            get;
            set;
        }
        public string ? Email {
            get;
            set;
        }
        public string ? Password {
            get;
            set;
        }
        public string ? ShopName {
            get;
            set;
        }
        public string ? BusinessType {
            get;
            set;
        }
        public string ? UserRole {
            get;
            set;
        }
        public bool ? IsDeleted {
            get;
            set;
        }
    }
}

AppSetting.Json Properties

In App setting Json File we are going to set the JSON Web Tokens Keys like

"JsonWebTokenKeys": {
    "ValidateIssuerSigningKey": true,
    "IssuerSigningKey": "64A63153-11C1-4919-9133-EFAF99A9B456",
    "ValidateIssuer": true,
    "ValidIssuer": "https://localhost:7212",
    "ValidateAudience": true,
    "ValidAudience": "https://localhost:7212",
    "RequireExpirationTime": true,
    "ValidateLifetime": true
},

Program.cs Class

Configure the Identity and JWT Token in Program.cs Class

using JWTTokenAuthInAspNet6_BAL.Services;
using JWTTokenAuthInAspNet6_DAL.Contracts;
using JWTTokenAuthInAspNet6_DAL.Data;
using JWTTokenAuthInAspNet6_DAL.Models;
using JWTTokenAuthInAspNet6_DAL.Repositories;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//Sql Dependency Injection
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext < AppDbContext > (options => options.UseSqlServer(connectionString));
//Add Service Injection
builder.Services.AddSingleton < IRepository < AppUser > , RepositoryAppUser > ();
builder.Services.AddSingleton < ServiceAppUser, ServiceAppUser > ();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => {
    c.SwaggerDoc("v1", new OpenApiInfo {
        Title = "JWTToken_Auth_API", Version = "v1"
    });
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() {
        Name = "Authorization",
            Type = SecuritySchemeType.ApiKey,
            Scheme = "Bearer",
            BearerFormat = "JWT",
            In = ParameterLocation.Header,
            Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 1safsfsdfdfd\"",
    });
    c.AddSecurityRequirement(new OpenApiSecurityRequirement {
        {
            new OpenApiSecurityScheme {
                Reference = new OpenApiReference {
                    Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                }
            },
            new string[] {}
        }
    });
});
//Add Identity
builder.Services.AddIdentity < AppUser, IdentityRole > ().AddEntityFrameworkStores < AppDbContext > ();
//Add Jwt Token Functionality
// Add Authencation
builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.SaveToken = true;
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = new TokenValidationParameters() {
        ValidateIssuerSigningKey = bool.Parse(builder.Configuration["JsonWebTokenKeys:ValidateIssuerSigningKey"]),
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JsonWebTokenKeys:IssuerSigningKey"])),
            ValidateIssuer = bool.Parse(builder.Configuration["JsonWebTokenKeys:ValidateIssuer"]),
            ValidAudience = builder.Configuration["JsonWebTokenKeys:ValidAudience"],
            ValidIssuer = builder.Configuration["JsonWebTokenKeys:ValidIssuer"],
            ValidateAudience = bool.Parse(builder.Configuration["JsonWebTokenKeys:ValidateAudience"]),
            RequireExpirationTime = bool.Parse(builder.Configuration["JsonWebTokenKeys:RequireExpirationTime"]),
            ValidateLifetime = bool.Parse(builder.Configuration["JsonWebTokenKeys:ValidateLifetime"])
    };
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsProduction()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

Controller

In the Controllers, we will write the Sign In and Register API End Point that is used to generate the Token when the user want to sign In to the Application.

Register API End Point

[HttpPost]
[Route("Register")]
public async Task < IActionResult > Register([FromBody] RegisterVM registerVM) {
    var IsExist = await userManager.FindByNameAsync(registerVM.Name);
    if (IsExist != null) return StatusCode(StatusCodes.Status500InternalServerError, new Response {
        Status = "Error", Message = "User already exists!"
    });
    AppUser appUser = new AppUser {
        UserName = registerVM.Name,
            AccountType = registerVM.AccountType,
            Email = registerVM.Email,
            PhoneNumber = registerVM.PhoneNo,
            Password = registerVM.Password,
            ShopName = registerVM.ShopName,
            BusinessType = registerVM.BusinessType,
            UserRole = registerVM.UserRole,
            IsDeleted = registerVM.IsDeleted
    };
    var result = await userManager.CreateAsync(appUser, registerVM.Password);
    if (!result.Succeeded) return StatusCode(StatusCodes.Status500InternalServerError, new Response {
        Status = "Error", Message = "User creation failed! Please check user details and try again."
    });
    if (!await roleManager.RoleExistsAsync(registerVM.UserRole)) await roleManager.CreateAsync(new IdentityRole(registerVM.UserRole));
    if (await roleManager.RoleExistsAsync(registerVM.UserRole)) {
        await userManager.AddToRoleAsync(appUser, registerVM.UserRole);
    }
    return Ok(new Response {
        Status = "Success", Message = "User created successfully!"
    });
}

Sign In API End Point

This API Endpoint will be used to generate the JWT Token when the user wants to sign in to the Application.

[HttpPost]
[Route("Login")]
public async Task < IActionResult > Login([FromBody] LoginVM loginVM) {
    //var user1 = await userManager.FindByIdAsync(loginVM.Id);
    var user = await userManager.FindByNameAsync(loginVM.UserName);
    if (user != null && await userManager.CheckPasswordAsync(user, loginVM.Password)) {
        var userRoles = await userManager.GetRolesAsync(user);
        var authClaims = new List < Claim > {
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.MobilePhone, user.PhoneNumber),
            new Claim(ClaimTypes.Email, user.Email),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        };
        foreach(var userRole in userRoles) {
            authClaims.Add(new Claim(ClaimTypes.Role, userRole));
        }
        var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JsonWebTokenKeys:IssuerSigningKey"]));
        var token = new JwtSecurityToken(expires: DateTime.Now.AddHours(3), claims: authClaims, signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256));
        return Ok(new {
            api_key = new JwtSecurityTokenHandler().WriteToken(token),
                expiration = token.ValidTo,
                user = user,
                Role = userRoles,
                status = "User Login Successfully"
        });
    }
    return Unauthorized();
}

Overall Controller Code

using JWTTokenAuthInAspNet6.Commons;
using JWTTokenAuthInAspNet6.ViewModels;
using JWTTokenAuthInAspNet6_DAL.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace JWTTokenAuthInAspNet6.Controllers {
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController: ControllerBase {
        private readonly UserManager < AppUser > userManager;
        private readonly RoleManager < IdentityRole > roleManager;
        private readonly IConfiguration _configuration;
        private readonly SignInManager < AppUser > signInManager;
        public AuthController(UserManager < AppUser > userManager, SignInManager < AppUser > signInManager, RoleManager < IdentityRole > roleManager, IConfiguration configuration) {
                this.userManager = userManager;
                this.roleManager = roleManager;
                _configuration = configuration;
                this.signInManager = signInManager;
            }
            [HttpPost]
            [Route("Register")]
        public async Task < IActionResult > Register([FromBody] RegisterVM registerVM) {
                var IsExist = await userManager.FindByNameAsync(registerVM.Name);
                if (IsExist != null) return StatusCode(StatusCodes.Status500InternalServerError, new Response {
                    Status = "Error", Message = "User already exists!"
                });
                AppUser appUser = new AppUser {
                    UserName = registerVM.Name,
                        AccountType = registerVM.AccountType,
                        Email = registerVM.Email,
                        PhoneNumber = registerVM.PhoneNo,
                        Password = registerVM.Password,
                        ShopName = registerVM.ShopName,
                        BusinessType = registerVM.BusinessType,
                        UserRole = registerVM.UserRole,
                        IsDeleted = registerVM.IsDeleted
                };
                var result = await userManager.CreateAsync(appUser, registerVM.Password);
                if (!result.Succeeded) return StatusCode(StatusCodes.Status500InternalServerError, new Response {
                    Status = "Error", Message = "User creation failed! Please check user details and try again."
                });
                if (!await roleManager.RoleExistsAsync(registerVM.UserRole)) await roleManager.CreateAsync(new IdentityRole(registerVM.UserRole));
                if (await roleManager.RoleExistsAsync(registerVM.UserRole)) {
                    await userManager.AddToRoleAsync(appUser, registerVM.UserRole);
                }
                return Ok(new Response {
                    Status = "Success", Message = "User created successfully!"
                });
            }
            [HttpPost]
            [Route("Login")]
        public async Task < IActionResult > Login([FromBody] LoginVM loginVM) {
            //var user1 = await userManager.FindByIdAsync(loginVM.Id);
            var user = await userManager.FindByNameAsync(loginVM.UserName);
            if (user != null && await userManager.CheckPasswordAsync(user, loginVM.Password)) {
                var userRoles = await userManager.GetRolesAsync(user);
                var authClaims = new List < Claim > {
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim(ClaimTypes.MobilePhone, user.PhoneNumber),
                    new Claim(ClaimTypes.Email, user.Email),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                };
                foreach(var userRole in userRoles) {
                    authClaims.Add(new Claim(ClaimTypes.Role, userRole));
                }
                var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JsonWebTokenKeys:IssuerSigningKey"]));
                var token = new JwtSecurityToken(expires: DateTime.Now.AddHours(3), claims: authClaims, signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256));
                return Ok(new {
                    api_key = new JwtSecurityTokenHandler().WriteToken(token),
                        expiration = token.ValidTo,
                        user = user,
                        Role = userRoles,
                        status = "User Login Successfully"
                });
            }
            return Unauthorized();
        }
    }
}

Output

Register the User

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Sign In user using Created Credentials

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

JWT Token Authentication in Asp.net Core 6 Web API Using Three Tier Architecture

Here we have the complete object of the user and JWT Token

Conclusion

JSON Web Token is an open standard that allows transmitting the data between parties as a JSON it is digitally signed so the information is trusted and verified JWT Token can be signed using secret (with HMAC Algorithm) or with the public or private key pairs using RSA Or ECDSA JWT Token Authentication is very popular in Website Development.

In this article, we have implemented the JWT Token Authentication using Three Tier Architecture

Download Code

If you want to down the complete project, then follow this link.