JWT Authentication in ASP.NET Core: Complete Beginner's Guide

Authentication is one of the most important aspects of modern web application development. When building APIs, you need a secure way to verify the identity of users and control access to protected resources.

JSON Web Tokens (JWT) have become one of the most popular solutions for securing ASP.NET Core APIs because they are lightweight, scalable, and easy to integrate with web, mobile, and desktop applications.

In this tutorial, you'll learn how JWT Authentication works, how to configure it in ASP.NET Core, generate tokens, protect API endpoints, and follow security best practices.


Topics Covered
  • What is JWT?
  • Authentication vs Authorization
  • JWT Structure
  • Configuring JWT Authentication
  • Generating Tokens
  • Protecting API Endpoints
  • Using Claims
  • Security Best Practices

What Is JWT?

JWT stands for JSON Web Token. It is a compact, URL-safe token format used to securely transmit information between parties.

After a user successfully logs in, the server generates a token and returns it to the client. The client then sends the token with future requests to prove its identity.

JWT is commonly used in:

  • ASP.NET Core Web APIs
  • Single Page Applications (SPA)
  • Mobile Applications
  • Microservices
  • Cloud-based systems

Authentication vs Authorization

Concept Description
Authentication Verifies who the user is.
Authorization Determines what the user can access.

JWT primarily handles authentication, but it can also contain authorization information such as user roles and permissions.

JWT Token Structure

A JWT consists of three parts separated by periods:


        Header.Payload.Signature
    

Example:


        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
        .
        eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiJ9
        .
        abc123xyz456
    

Header

Contains token metadata such as the signing algorithm.

Payload

Contains claims about the user.

Signature

Ensures the token has not been modified.

Create a New ASP.NET Core Web API


        dotnet new webapi -n JwtDemo

        cd JwtDemo
    

Run the application:


        dotnet run
    

Install JWT Package


        dotnet add package
        Microsoft.AspNetCore.Authentication.JwtBearer
    

This package provides JWT authentication support for ASP.NET Core.

Add JWT Settings

Store configuration values inside appsettings.json.


        {
        "Jwt": {
        "Key": "YourVeryStrongSecretKey",
        "Issuer": "CSharpHub",
        "Audience": "CSharpHubUsers"
        }
        }
    
Important: Never store production secrets directly in source control. Use environment variables, User Secrets, or secure secret storage solutions.

Configure Authentication

Register JWT authentication in Program.cs.


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

        var key =
        Encoding.UTF8.GetBytes(
        builder.Configuration["Jwt:Key"]);

        builder.Services
        .AddAuthentication(
        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(key)
        };
        });
    

Enable Authentication Middleware


        app.UseAuthentication();

        app.UseAuthorization();
    

Authentication middleware should be registered before authorization.

Create a Login Model


        public class LoginRequest
        {
        public string Username { get; set; } = "";

        public string Password { get; set; } = "";
        }
    

Generate JWT Tokens


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

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

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

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

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

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

Create a Login Endpoint


        [HttpPost("login")]
        public IActionResult Login(
        LoginRequest request)
        {
        if (request.Username == "admin" &&
        request.Password == "password")
        {
        var token =
        GenerateToken(
        request.Username);

        return Ok(new
        {
        Token = token
        });
        }

        return Unauthorized();
        }
    

After successful authentication, the API returns a JWT token.

Protect Endpoints

Use the Authorize attribute to secure endpoints.


        using Microsoft.AspNetCore.Authorization;

        [Authorize]
        [HttpGet("profile")]
        public IActionResult Profile()
        {
        return Ok("Protected Data");
        }
    

Only authenticated users with valid tokens can access this endpoint.

Sending Tokens from Clients

Include the token in the Authorization header.


        Authorization:
        Bearer eyJhbGciOi...
    

ASP.NET Core automatically validates the token.

Using Claims

Claims store information about the authenticated user.


        var username =
        User.Identity?.Name;
    

        var role =
        User.FindFirst(
        ClaimTypes.Role)?.Value;
    

Claims can be used for role-based authorization.

Role-Based Authorization


        [Authorize(Roles = "Admin")]
        [HttpGet("admin")]
        public IActionResult AdminOnly()
        {
        return Ok();
        }
    

Only users with the Admin role can access the endpoint.

Common JWT Mistakes

  • Using weak secret keys.
  • Storing secrets in source code.
  • Creating tokens that never expire.
  • Skipping HTTPS.
  • Trusting client-side validation.
  • Exposing sensitive information inside claims.

JWT Security Best Practices

  • Use strong signing keys.
  • Store secrets securely.
  • Always use HTTPS.
  • Set reasonable expiration times.
  • Implement refresh tokens when needed.
  • Validate all incoming tokens.
  • Use role-based authorization carefully.

Frequently Asked Questions

Why use JWT instead of sessions?

JWT works well in distributed systems because the server does not need to store session data for every user.

Can JWT be used with ASP.NET Core APIs?

Yes. JWT is one of the most common authentication methods for ASP.NET Core Web APIs.

Should JWT tokens expire?

Yes. Tokens should always have an expiration time to reduce security risks.

Can JWT contain user roles?

Yes. Claims can store roles and permissions used for authorization.

Related Tutorials

Conclusion

JWT Authentication provides a secure and scalable way to protect ASP.NET Core applications and APIs. By understanding token generation, validation, claims, and authorization, you can build secure systems that support modern web and mobile applications.

Combining JWT with HTTPS, strong secret management, and proper authorization strategies will help keep your applications secure while providing a smooth user experience.