.NET 7 Web API π JWT Authentication and role-based Authorization
--
A step-by-step guide to user authentication using ASP.NET Core 7, Identity, MSSQL
Create a minimal API project in Visual Studio 2022.
π» GitHub: https://github.com/shahedbd/API.UserManagement
JWT (JSON Web Token) authentication is a popular method of implementing authentication and authorization in modern web applications. In ASP.NET Core, JWT authentication is built into the framework and can be easily configured in your application.
After completing this guide you will have created an ASP.NET 7 web API that exposes a secure endpoint. The secure endpoint can only be accessed by users who have a registered account in your system.
π Table of Contents:
β
1. Create Project: Using Visual Studio 2022
- API Project, Dotnet 7.0, and a class library project for data connectivity and migration
β 2. Install the Required Packages
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer β version 7.0.4
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore β version 7.0.4
dotnet add package Microsoft.EntityFrameworkCore.SqlServer β version 7.0.4
dotnet add package Microsoft.EntityFrameworkCore.Tools β version 7.0.4
β
3. Database connection: MSSQL: appsettings.json
β
4. Create models and complete ApplicationDbContext class
β
5. Update program.cs: AddDbContext
β
6. Database Migration
dotnet ef migrations add InitialCreate
dotnet ef database update
β using PMC
PM: add-migration initcreate
PM: update-database
β
7. Create Auth Controller
β
8. Crete Auth Service
β
9. Test API using postman
β
10. Deploy to IIS
β
11. Test API from IIS hosting
Auth Service
public class AuthService : IAuthService
{
private readonly UserManager<ApplicationUser> userManager;
private readonly RoleManager<IdentityRole> roleManager;
private readonly IConfiguration _configuration;
public AuthService(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, IConfiguration configuration)
{
this.userManager = userManager;
this.roleManager = roleManager;
_configuration = configuration;
}
public async Task<(int,string)> Registeration(RegistrationModel model,string role)
{
var userExists = await userManager.FindByNameAsync(model.Username);
if (userExists != null)
return (0, "User already exists");
ApplicationUser user = new()
{
Email = model.Email,
SecurityStamp = Guid.NewGuid().ToString(),
UserName = model.Username,
FirstName = model.FirstName,
LastName = model.LastName,
};
var createUserResult = await userManager.CreateAsync(user, model.Password);
if (!createUserResult.Succeeded)
return (0,"User creation failed! Please check user details and try again.");
if (!await roleManager.RoleExistsAsync(role))
await roleManager.CreateAsync(new IdentityRole(role));
if (await roleManager.RoleExistsAsync(role))
await userManager.AddToRoleAsync(user, role);
return (1,"User created successfully!");
}
public async Task<(int,string)> Login(LoginModel model)
{
var user = await userManager.FindByNameAsync(model.Username);
if (user == null)
return (0, "Invalid username");
if (!await userManager.CheckPasswordAsync(user, model.Password))
return (0, "Invalid password");
var userRoles = await userManager.GetRolesAsync(user);
var authClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
foreach (var userRole in userRoles)
{
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
}
string token = GenerateToken(authClaims);
return (1, token);
}
private string GenerateToken(IEnumerable<Claim> claims)
{
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWTKey:Secret"]));
var _TokenExpiryTimeInHour = Convert.ToInt64(_configuration["JWTKey:TokenExpiryTimeInHour"]);
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = _configuration["JWTKey:ValidIssuer"],
Audience = _configuration["JWTKey:ValidAudience"],
//Expires = DateTime.UtcNow.AddHours(_TokenExpiryTimeInHour),
Expires = DateTime.UtcNow.AddMinutes(1),
SigningCredentials = new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256),
Subject = new ClaimsIdentity(claims)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
Application DB Context
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"connMSSQLNoCred": "Server=DESKTOP-99Q87I2\\MSSQLSERVER2017;Database=APIUserManagement;Trusted_Connection=True;MultipleActiveResultSets=true",
"connMSSQL": "Server=DESKTOP-99Q87I2\\MSSQLSERVER2017;Database=APIUserManagement;User ID=sa;Password=dev123456;MultipleActiveResultSets=true;TrustServerCertificate=True"
},
"JWTKey": {
"ValidAudience": "https://localhost:5001",
"ValidIssuer": "https://localhost:5001",
"TokenExpiryTimeInHour": "3",
"Secret": "ecawiasqrpqrgyhwnolrudpbsrwaynbqdayndnmcehjnwqyouikpodzaqxivwkconwqbhrmxfgccbxbyljguwlxhdlcvxlutbnwjlgpfhjgqbegtbxbvwnacyqnltrby"
},
"AllowedHosts": "*"
}
Configure Identity and JWT
// For Identity
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Adding Authentication
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Adding Jwt Bearer
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = builder.Configuration["JWTKey:ValidAudience"],
ValidIssuer = builder.Configuration["JWTKey:ValidIssuer"],
ClockSkew = TimeSpan.Zero,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWTKey:Secret"]))
};
});
Overall, JWT authentication provides a secure and efficient way to authenticate and authorize users in ASP.NET Core applications. It is widely used in modern web development and can be easily configured in ASP.NET Core.
Congratulations on making it this far! Really good job.
You have now created a secure API endpoint only accessible by authenticated users who have a valid JWT token. As well as the functionality for users to sign up and to login.
π Main Profile
β Business ERP Solution/Product/POS/Company Management
β School/College/University Management ERP
β Dashboard Template | ASP.NET Core MVC Web Starter Kit
β Advance POS System with Stock Manager | ASP.NET Core | EF Core | .NET Core 6.0
β Asset Management System with Barcode | ASP.NET Core | EF Core | .NET Core 6.0
β Advanced Files & Users Management | ASP.NET Core | EF Core | .NET Core | MSSQL | MySQL
β
Hospital and Pharmacy Management System | ASP.NET Core | EF Core:
https://1.envato.market/OR5o6N
β Inventory and User Management System
β Invoice Gen(Invoice Generation and Management) using .Net Core and EF
β Complaint | Issue | Helpdesk Ticket | My Ticket HelpDesk Support System | ASP.NET Core | EF Core
β ASP.NET Core CRUD Operation Using Dot Net 6.0 | MVC| MSSQL | MySQL | EF Core Code First | jQuery
β
ASP.NET Core full CRUD with .NET 5 | MSSQL/MySQL | EF code first:
https://1.envato.market/OR551W
β Staff | Employee Leave Management System
β Library Management System | ASP.NET Core | MSSQL | Code First