.NET Core  

Secure ASP.NET Core Web API Endpoints with JWT

πŸ“ŒWhat We'll Cover

  • βœ… Setup JWT Authentication
  • βœ… Create User Registration and Login
  • βœ… Secure API Endpoints
  • βœ… Add Role-Based Authorization
  • βœ… Test using Postman or Swagger

πŸ› οΈ Step 1. Create a New .NET Core Web API Project

dotnet new webapi -n SecureApiDemo
cd SecureApiDemo

πŸ”Ή Step 2. Install Required NuGet Packages

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.IdentityModel.Tokens
dotnet add package System.IdentityModel.Tokens.Jwt

πŸ” Step 3. Configure JWT Settings

3.1 Add JWT Configuration to appsettings.json

"JwtSettings": {
  "Secret": "THIS_IS_A_VERY_SECRET_KEY_123456",  
  "Issuer": "SecureApiDemo",
  "Audience": "SecureApiUser",
  "ExpiryMinutes": 60
}

πŸ”Ή Step 4. Add User Model and Auth DTOs

// Models/User.cs
public class User
{
    public string Username { get; set; }
    public string Password { get; set; } // Hash in real-world apps
    public string Role { get; set; } = "User";
}
// DTOs/LoginRequest.cs
public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
}
// DTOs/AuthResponse.cs
public class AuthResponse
{
    public string Token { get; set; }
    public string Username { get; set; }
    public string Role { get; set; }
}

πŸ”Ή Step 5. Create a JWT Token Generator

// Services/TokenService.cs
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

public class TokenService
{
    private readonly IConfiguration _config;

    public TokenService(IConfiguration config)
    {
        _config = config;
    }

    public string CreateToken(User user)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, user.Username),
            new Claim(ClaimTypes.Role, user.Role)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["JwtSettings:Secret"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        var expiry = DateTime.UtcNow.AddMinutes(Convert.ToDouble(_config["JwtSettings:ExpiryMinutes"]));

        var token = new JwtSecurityToken(
            issuer: _config["JwtSettings:Issuer"],
            audience: _config["JwtSettings:Audience"],
            claims: claims,
            expires: expiry,
            signingCredentials: creds);

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

πŸ”Ή Step 6. Register JWT and Services in Program.cs

builder.Services.AddSingleton<TokenService>();

var jwtSettings = builder.Configuration.GetSection("JwtSettings");
var secretKey = Encoding.UTF8.GetBytes(jwtSettings["Secret"]);

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtSettings["Issuer"],
            ValidAudience = jwtSettings["Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(secretKey)
        };
    });

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseAuthentication();  // πŸ‘ˆ important!
app.UseAuthorization();

πŸ”Ή Step 7. Create AuthController

// Controllers/AuthController.cs
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private static List<User> users = new(); // Replace with DB in real apps
    private readonly TokenService _tokenService;

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

    [HttpPost("register")]
    public IActionResult Register([FromBody] User user)
    {
        if (users.Any(u => u.Username == user.Username))
            return BadRequest("User already exists");

        users.Add(user);
        return Ok("User registered successfully");
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        var user = users.FirstOrDefault(u => u.Username == request.Username && u.Password == request.Password);
        if (user == null) return Unauthorized();

        var token = _tokenService.CreateToken(user);
        return Ok(new AuthResponse { Token = token, Username = user.Username, Role = user.Role });
    }
}

πŸ”Ή Step 8. Secure Endpoints Using [Authorize]

// Controllers/ProtectedController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class ProtectedController : ControllerBase
{
    [HttpGet("public")]
    public IActionResult Public() => Ok("This is a public endpoint");

    [HttpGet("user")]
    [Authorize]
    public IActionResult UserAccess() => Ok("You are an authenticated user");

    [HttpGet("admin")]
    [Authorize(Roles = "Admin")]
    public IActionResult AdminAccess() => Ok("You are an Admin");
}

πŸ”Ή Step 9. Testing with Postman or Swagger

9.1. Register a User

POST /api/auth/register
{
  "username": "john",
  "password": "1234",
  "role": "Admin"
}

9.2. Login

POST /api/auth/login
{
  "username": "john",
  "password": "1234"
}

πŸ” Copy the token from the response.

9.3. Use Token for Authorized Endpoints

  • In Postman/Swagger, set the header
    Authorization: Bearer <your-token>
    Now test
  • /api/protected/public – accessible by anyone
  • /api/protected/user – requires any logged-in user
  • /api/protected/admin – only for role = Admin

πŸ” Summary

Feature Status
User Registration βœ…
User Login & Token βœ…
JWT Authentication βœ…
Role-based Security βœ…
Secure Endpoints βœ…

πŸ“˜ Bonus Tips

  • In production, store passwords hashed (e.g., BCrypt)
  • Store JWT secret in environment variables
  • Use ASP.NET Identity for more advanced user management