ASP.NET Core  

How to Secure REST APIs Using JWT in .NET Core?

Introduction

Securing REST APIs using JWT in .NET Core is one of the most common and reliable approaches for protecting modern web applications, mobile backends, and cloud-native microservices. JWT (JSON Web Token) authentication allows stateless, secure, and scalable API communication between clients and servers. In ASP.NET Core Web API development, JWT-based security is widely used for enterprise applications, SaaS platforms, and distributed systems.

This guide explains, in simple terms, how to secure REST APIs with JWT in .NET Core, including configuration, token generation, validation, and production best practices.

What Is JWT (JSON Web Token)?

JWT stands for JSON Web Token. It is a compact, URL-safe token format used to securely transmit information between two parties. A JWT contains three main parts:

  • Header – Contains token type and signing algorithm

  • Payload – Contains claims such as user ID, roles, or permissions

  • Signature – Ensures the token has not been tampered with

JWT is stateless, meaning the server does not store session data. Each request includes the token, and the server validates it.

Why Use JWT to Secure REST APIs?

JWT authentication in .NET Core provides several benefits:

  • Stateless authentication (no server session storage)

  • Scalable for microservices architecture

  • Secure API communication over HTTPS

  • Easy integration with mobile and SPA applications

  • Works well in cloud-native and containerized deployments

Because of these advantages, JWT is commonly used in ASP.NET Core Web API security implementations.

Step 1: Install Required JWT Package

Install the JWT authentication package in your .NET Core project:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

This package enables JWT token validation in ASP.NET Core applications.

Step 2: Configure JWT Authentication in Program.cs

Add authentication services in Program.cs:

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", 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"]))
        };
    });

builder.Services.AddAuthorization();

Enable middleware in correct order:

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

Middleware order is critical for securing REST APIs in ASP.NET Core.

Step 3: Add JWT Configuration in appsettings.json

Store JWT configuration securely:

"Jwt": {
  "Key": "your_super_secure_secret_key",
  "Issuer": "yourdomain.com",
  "Audience": "yourdomain.com"
}

For production environments, store secrets in environment variables or Azure Key Vault instead of hardcoding them.

Step 4: Generate JWT Token

Create a method to generate tokens after successful login.

public string GenerateToken(string username)
{
    var claims = new[]
    {
        new Claim(ClaimTypes.Name, username)
    };

    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.UtcNow.AddHours(1),
        signingCredentials: creds);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

This token is returned to the client after login.

Step 5: Secure API Endpoints

Protect REST API endpoints using the Authorize attribute:

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("Secure data");
    }
}

Only requests with a valid JWT token in the Authorization header will access this endpoint.

Client request example:

Authorization: Bearer YOUR_JWT_TOKEN

Step 6: Implement Role-Based Authorization (Optional)

You can include roles in the token claims:

new Claim(ClaimTypes.Role, "Admin")

Then restrict access:

[Authorize(Roles = "Admin")]

This enables secure role-based access control in ASP.NET Core REST APIs.

Best Practices for Securing REST APIs Using JWT

  • Always use HTTPS for API communication

  • Store JWT secret keys securely

  • Set reasonable token expiration time

  • Implement refresh tokens for long sessions

  • Log authentication failures

  • Validate all input data

  • Avoid storing sensitive data in JWT payload

These best practices improve API security in enterprise .NET Core applications.

Common Mistakes When Using JWT in .NET Core

  • Forgetting to enable UseAuthentication middleware

  • Incorrect secret key configuration

  • Token expiration misconfiguration

  • Using weak signing keys

  • Not validating issuer and audience

  • Sending token without "Bearer" prefix

Carefully reviewing these issues helps prevent authentication failures.

Summary

Securing REST APIs using JWT in .NET Core involves configuring JWT authentication middleware, defining token validation parameters, generating signed JSON Web Tokens after user authentication, and protecting endpoints using the Authorize attribute. By implementing secure key management, HTTPS enforcement, proper token expiration, and optional role-based authorization, developers can build scalable, stateless, and secure ASP.NET Core Web APIs suitable for enterprise, cloud-native, and microservices-based applications. Proper configuration and adherence to security best practices ensure reliable authentication and strong API protection in modern .NET environments.