Secure Your .NET 8 Web API with JWT Bearer Authentication (Step by Step)
CLOUD COMPUTING

Introduction

JSON Web Tokens (JWT) are an industry standard for securely transmitting information between parties. In this tutorial, we will implement JWT bearer authentication in a .NET 8 Web API application. By the end, your API will be protected, allowing access only to authenticated users.


Prerequisites

  • .NET SDK 8 installed

  • Visual Studio or any preferred code editor

  • Basic knowledge of C# and Web API


Step 1: Create a New .NET 8 Web API Project

  1. Open a terminal and run the following command to create a new Web API project:

    dotnet new webapi -n JwtAuthDemo
  2. Navigate to the project directory:

    cd JwtAuthDemo
  3. Open the project in your code editor.

  4. Run the project to ensure it’s working:

    dotnet run

    Visit https://localhost:5001 to confirm the API is running.


Step 2: Add JWT NuGet Packages

Install the required NuGet packages for JWT authentication:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

This package provides middleware for JWT-based authentication.


Step 3: Configure JWT Authentication in Program.cs

Open Program.cs and configure JWT authentication.

Code Example:

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

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

// Add JWT Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "https://yourdomain.com",
            ValidAudience = "https://yourdomain.com",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSuperSecretKey"))
        };
    });

var app = builder.Build();

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

app.MapControllers();

app.Run();

Explanation:

  • ValidateIssuer: Ensures the token was issued by a trusted server.

  • ValidateAudience: Ensures the token is for a valid audience.

  • IssuerSigningKey: A secret key used to validate the token signature.

Replace YourSuperSecretKey with a secure, random string.


Step 4: Create a Token Service

Create a service to generate JWT tokens.

  1. Add a new folder named Services.

  2. Create a file TokenService.cs in the Services folder.

Code Example:

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

public class TokenService
{
    private const string SecretKey = "YourSuperSecretKey";
    private const string Issuer = "https://yourdomain.com";

    public string GenerateToken(string username)
    {
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: Issuer,
            audience: Issuer,
            claims: claims,
            expires: DateTime.Now.AddMinutes(30),
            signingCredentials: creds
        );

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

Step 5: Create a Login Endpoint

Create a controller to authenticate users and generate tokens.

  1. Add a new controller named AuthController.cs in the Controllers folder.

Code Example:

using Microsoft.AspNetCore.Mvc;

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

    public AuthController()
    {
        _tokenService = new TokenService();
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        // Dummy authentication logic
        if (request.Username == "admin" && request.Password == "password")
        {
            var token = _tokenService.GenerateToken(request.Username);
            return Ok(new { Token = token });
        }

        return Unauthorized();
    }
}

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

Step 6: Secure Endpoints

Secure API endpoints by adding the [Authorize] attribute.

Code Example:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class WeatherController : ControllerBase
{
    [HttpGet]
    [Authorize]
    public IActionResult Get()
    {
        return Ok(new { Weather = "Sunny", Temperature = "25°C" });
    }
}

Step 7: Test the Implementation

  1. Use a tool like Postman or curl to test your API.

  2. Authenticate by sending a POST request to /api/auth/login with the following JSON body:

    {
        "username": "admin",
        "password": "password"
    }
  3. Copy the returned token and include it in the Authorization header when accessing secured endpoints:

    Authorization: Bearer <YourToken>

Francis Kingori

Francis Kingori

Updated on: Dec 23, 2024 | 1 viewers