Implementing JWT Authentication in .NET Core
 in .NET
This guide demonstrates JWT authentication implementation in .NET Core with custom configurations and error handling.
1. NuGet Package Installation
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
2. Configuration Settings
appsettings.json
{
  "JWT": {
    "ClockSkew": 10,
    "ValidAudience": "https://meowv.com",
    "ValidIssuer": "StarPlus",
    "IssuerSigningKey": "6Zi/5pifUGx1c+... (base64 key)",
    "Expires": 30
  }
}
3. Service Configuration
Startup.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromSeconds(
                    Convert.ToInt32(Configuration["JWT:ClockSkew"])),
                ValidAudience = Configuration["JWT:ValidAudience"],
                ValidIssuer = Configuration["JWT:ValidIssuer"],
                IssuerSigningKey = new SymmetricSecurityKey(
                    Encoding.UTF8.GetBytes(Configuration["JWT:IssuerSigningKey"]))
            };
        });
services.AddAuthorization();
4. Token Generation Endpoint
AuthController.cs
[HttpGet("Token")]
public string GenerateToken(string username, string password)
{
    if (username == "meowv" && password == "123")
    {
        var claims = new[] {
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.Email, "123@meowv.com"),
            new Claim(JwtRegisteredClaimNames.Exp, 
                DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeSeconds().ToString())
        };
        var credentials = new SigningCredentials(
            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:IssuerSigningKey"])),
            SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(
            issuer: Configuration["JWT:ValidIssuer"],
            audience: Configuration["JWT:ValidAudience"],
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(30),
            signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
    throw new UnauthorizedAccessException("Invalid credentials");
}
Sample Output:
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
5. Protected Endpoints
[Authorize]
[HttpGet("secure-data")]
public IActionResult GetSecureData() => Ok("Protected resource");
[AllowAnonymous] 
[HttpGet("public-data")]
public IActionResult GetPublicData() => Ok("Public resource");
Authorization Test Results:
/secure-datawithout token: 401 Unauthorized/secure-datawith valid token: 200 OK/public-data: Always accessible
6. Custom Error Handling
Custom 401 Response
options.Events = new JwtBearerEvents {
    OnChallenge = async context => {
        context.HandleResponse();
        context.Response.StatusCode = 401;
        await context.Response.WriteAsync(
            JsonSerializer.Serialize(new {
                success = false,
                message = "Authentication required"
            }));
    }
};
7. Alternative Token Locations
Query Parameter Support
options.Events = new JwtBearerEvents {
    OnMessageReceived = context => {
        context.Token = context.Request.Query["access_token"];
        return Task.CompletedTask;
    }
};
Usage:
GET /api/data?access_token=eyJhbGciOiJIUzI1NiIs...
Key Features
- Configurable expiration and clock skew
 - Customizable error responses
 - Multiple token location support (Header/Query/Cookie)
 - Claims-based authorization
 - Standard-compliant JWT validation
 
Always store signing keys securely and rotate them periodically for production systems.
Tags:
.NET Corejwt