JWT (JSON Web Token) is a secure, compact means of transmitting identity information between parties as a JSON object, often used for stateless authentication in APIs.

Step-by-Step JWT Implementation in .NET 8 API

1. Create a New .NET 8 Web API Project

dotnet new webapi -n JwtAuthDemo
cd JwtAuthDemo

2. Add NuGet Package

You may not need to install anything manually since .NET 8 includes JWT libraries, but just in case:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

3. Configure JWT in appsettings.json

{ "Jwt": { "Key": "ThisIsASecretKeyForJWTDoNotShare", "Issuer": "JwtAuthDemo", "Audience": "JwtAuthDemoClient", "ExpiresInMinutes": 60 }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*"
}

4. Create a JWT Token Service

Create Services/JwtTokenService.cs:

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
public class JwtTokenService
{ private readonly IConfiguration _configuration; public JwtTokenService(IConfiguration configuration) { _configuration = configuration; } public string GenerateToken(string username) { var key = Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]); var issuer = _configuration["Jwt:Issuer"]; var audience = _configuration["Jwt:Audience"]; var expires = DateTime.UtcNow.AddMinutes(double.Parse(_configuration["Jwt:ExpiresInMinutes"])); var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, username), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; var token = new JwtSecurityToken( issuer: issuer, audience: audience, claims: claims, expires: expires, signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256) ); return new JwtSecurityTokenHandler().WriteToken(token); }
}

5. Register JWT Authentication in Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register JWT service
builder.Services.AddSingleton<JwtTokenService>();
// Add JWT Authentication
builder.Services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { var jwt = builder.Configuration.GetSection("Jwt"); options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwt["Issuer"], ValidAudience = jwt["Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwt["Key"])) }; });
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication(); // 🔐 Must be before UseAuthorization
app.UseAuthorization();
app.MapControllers();
app.Run();

6. Create an Authentication Controller

Create Controllers/AuthController.cs:

using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{ private readonly JwtTokenService _jwtService; public AuthController(JwtTokenService jwtService) { _jwtService = jwtService; } [HttpPost("login")] public IActionResult Login([FromBody] LoginRequest login) { if (login.Username == "admin" && login.Password == "password") { var token = _jwtService.GenerateToken(login.Username); return Ok(new { token }); } return Unauthorized("Invalid credentials"); }
}
public record LoginRequest(string Username, string Password);

7. Secure an API Endpoint

Create a secured controller Controllers/SecureController.cs:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class SecureController : ControllerBase
{ [HttpGet("data")] [Authorize] public IActionResult GetSecureData() { return Ok(new { message = "You are authorized to access this data!" }); }
}

8. Test with Swagger or Postman

First, call POST /api/auth/login with:

{ "username": "admin", "password": "password"
}

Copy the token returned.

Call GET /api/secure/data with Authorization header:

Authorization: Bearer <your_token_here>

Conclusion:

JWT authentication in .NET 8 lets you securely manage user access in your APIs. You set up a token system that verifies users when they log in and protects specific endpoints from unauthorized access. After logging in, users receive a token, which they must include in future requests to access secure data. This method helps create a simple, secure, and stateless way to handle user authentication.