JWT Authentication in ASP.NET Core 8 Web API Step-by-Step Guide

How to Implement JWT Authentication In ASP.NET Core 8 Web API (Step-by-Step)

What is JWT Authentication in ASP.NET Core 8?

Stateless
Secure
Scalable
Ideal for Web APIs

Why JWT Authentication is Important

JWT vs Traditional Session Authentication

Authentication vs Authorization

What is JWT?

Structure of a JWT Token

Header.Payload.Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

1. Header

{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload

{
  "sub": "1234567890",
  "name": "admin",
  "role": "Admin",
  "department": "IT",
  "iat": 1612309123
}

3. Signature

How JWT Authentication Works in ASP.NET Core 8

Authorization: Bearer your_token
JWT Authentication Flow in ASP.NET Core 8 Web API

Step-by-Step Implementation

Step 1: Create ASP.NET Core 8 Web API Project

Step 2: Install Required NuGet Package

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 8.0.0

Step 3: Add JWT Configuration in appsettings.json File

"Jwt": {
  "Key": "ThisIsMySuperSecretKeyForJwtAuthentication2024!@#",
  "Issuer": "JwtAuthDemo",
  "Audience": "JwtAuthDemoUsers",
  "DurationInMinutes": 60
}

Step 4: Configure JWT Authentication in Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "JWT Authentication API",
        Version = "v1"
    });
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Name = "Authorization",
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Description = "Enter JWT Token like: Bearer {your token}"
    });

    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
        ClockSkew = TimeSpan.Zero
    };
});

builder.Services.AddAuthorization();

var app = builder.Build();

// Enable Swagger (Development Only)
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Step 5: Create User Model

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Step 6: Create Login API to Generate JWT Token

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
    private readonly IConfiguration _configuration;

    public AuthController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] User loginUser)
    {
        if (loginUser.Username == "admin" && loginUser.Password == "123")
        {
            var claims = new[]
            {
                new Claim(ClaimTypes.Name, loginUser.Username),
                new Claim(ClaimTypes.Role, "Admin")
            };

            var key = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(60),
                signingCredentials: creds);

            return Ok(new
            {
                token = new JwtSecurityTokenHandler().WriteToken(token)
            });
        }

        return Unauthorized();
    }
}

Step 7: Protect API Endpoints

using Microsoft.AspNetCore.Authorization;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("This is protected data.");
    }
}

Step 8: Implement Role-Based Authorization

[Authorize(Roles = "Admin")]
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
    return Ok("Deleted successfully");
}

Important Note:

new Claim(ClaimTypes.Role, "Admin")
[Authorize(Roles = "Admin,Manager")]

Step 9: Security Best Practices

JWT vs Cookies vs OAuth2

Testing JWT Authentication in Swagger

Bearer your_token_here
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

6. Click Authorize, then click Close.
7. Now test the protected endpoints.

JWT Authentication in ASP.NET Core 8 login endpoint tested in Swagger UI

Common Errors and Troubleshooting

Best Practices for Production

FAQ

Conclusion

Related Blogs You Might Like

🚀 Subscribe for Tech Updates

📧

👤

We respect your privacy. Unsubscribe anytime.