How to implement JWT authentication in ASP.NET Core
By FoxLearn 12/31/2024 9:27:49 AM 243
Minimal APIs are designed for building lightweight HTTP APIs, making them ideal for microservices. Securing these endpoints often involves adding JWT authentication to ensure that only authorized users can access certain parts of your API.
Steps to Secure Minimal API Endpoints with JWT Authentication
Begin by creating a new ASP.NET Core Web API project using Visual Studio 2022. In the "Create new project" window, select "ASP.NET Core Web API" and ensure that you don’t select "Use controllers," as we’ll be working with minimal APIs.
Create an API Endpoint
In the Program.cs
file, create a simple HTTP GET endpoint. Use .RequireAuthorization()
to enforce that authentication is required to access this endpoint.
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/secure/hello", () => "Hello, Secure World!").RequireAuthorization(); app.Run();
Install JWT Authentication Package
Next, Add the Microsoft.AspNetCore.Authentication.JwtBearer
NuGet package to the project.
Alternatively, you can install the package by using the NuGet Package Manager console and entering the following command.
PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
Next, create a section in the appsettings.json file to store the Issuer, Audience, and Key values, which will be used to generate a JSON Web Token.
Add the following information to your appsettings.json file:
"JwtSettings": { "Issuer": "https://example.com/", "Audience": "https://example.com/", "Key": "YourSecureSecretKeyHere1234" }
Configure JWT Authentication
In the Program.cs
file, configure the JWT authentication middleware. This will specify the settings for JWT validation, including the secret key, issuer, and audience.
builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])), ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true }; });
To add authorization services to your application, include the following code snippet in your Program.cs file:
builder.Services.AddAuthorization();
Add User Model
Create a User
model class to hold login credentials.
public class User { public string UserName { get; set; } public string Password { get; set; } }
This class will be used to authenticate users.
JWT Token Generation Endpoint
Create an HTTP POST endpoint to generate JWT tokens when a user provides valid credentials.
app.MapPost("/secure/login", [AllowAnonymous] (User user) => { if (user.UserName == "testuser" && user.Password == "password123") { var token = GenerateJwtToken(user); return Results.Ok(token); } return Results.Unauthorized(); });
This endpoint checks the user’s username and password, and if they are correct, generates and returns a token.
Generate JWT Token
Implement the GenerateJwtToken
method to create a signed JWT token using the JwtSecurityTokenHandler
class.
private string GenerateJwtToken(User user) { var issuer = builder.Configuration["Jwt:Issuer"]; var audience = builder.Configuration["Jwt:Audience"]; var key = Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"]); var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, user.UserName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddMinutes(30), Issuer = issuer, Audience = audience, SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); }
Use Authentication and Authorization
Ensure that the authentication and authorization middleware is added to the pipeline. This ensures that requests are authenticated before accessing secure endpoints.
app.UseAuthentication(); app.UseAuthorization();
Once the API is set up, you can use tools like Postman to test it. First, use the login endpoint (/secure/login
) to obtain a JWT. Then, include the token as a Bearer
token in the Authorization header when calling the /secure/hello
endpoint. If the token is valid, the API will return the secured message.
Example of the login request:
- POST:
/secure/login
- Body (JSON):
{ "UserName": "testuser", "Password": "password123" }
Example of the secured endpoint request:
- GET:
/secure/hello
- Authorization:
Bearer <JWT Token>
In this example, we’ve shown how to secure minimal API endpoints using JWT in ASP.NET Core. The process involves setting up JWT authentication, creating an endpoint for token generation, and securing other API routes.
- Content Negotiation in Web API
- How to fix 'InvalidOperationException: Scheme already exists: Bearer'
- How to fix System.InvalidOperationException: Scheme already exists: Identity.Application
- Add Thread ID to the Log File using Serilog
- Handling Exceptions in .NET Core API with Middleware
- InProcess Hosting in ASP.NET Core
- Limits on ThreadPool.SetMinThreads and SetMaxThreads
- Controlling DateTime Format in JSON Output with JsonSerializerOptions