RepletoryLib.Auth.Jwt 1.0.0

dotnet add package RepletoryLib.Auth.Jwt --version 1.0.0
                    
NuGet\Install-Package RepletoryLib.Auth.Jwt -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RepletoryLib.Auth.Jwt" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RepletoryLib.Auth.Jwt" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="RepletoryLib.Auth.Jwt" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RepletoryLib.Auth.Jwt --version 1.0.0
                    
#r "nuget: RepletoryLib.Auth.Jwt, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RepletoryLib.Auth.Jwt@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RepletoryLib.Auth.Jwt&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=RepletoryLib.Auth.Jwt&version=1.0.0
                    
Install as a Cake Tool

RepletoryLib.Auth.Jwt

JWT authentication with access tokens, refresh tokens, revocation, and user context extraction.

Part of the RepletoryLib ecosystem -- standalone, reusable .NET 10 libraries with zero business logic.

NuGet .NET 10 License: MIT


Overview

RepletoryLib.Auth.Jwt provides a complete JWT authentication solution for ASP.NET Core applications. It handles access token generation with custom claims, refresh token management, token revocation via cache-based blacklisting, and automatic extraction of the current user from JWT claims.

Key Features

  • Access token generation -- JWT with configurable claims, roles, tenant, and custom data
  • Refresh tokens -- Secure refresh flow with configurable expiry
  • Token revocation -- Blacklist revoked tokens via ICacheService
  • ICurrentUserService -- Extracts user context (ID, name, roles, tenant) from JWT claims
  • ASP.NET Core integration -- Configures AddAuthentication().AddJwtBearer() automatically

Installation

dotnet add package RepletoryLib.Auth.Jwt

Dependencies

Package Type
RepletoryLib.Common RepletoryLib
RepletoryLib.Caching.Abstractions RepletoryLib
Microsoft.AspNetCore.Authentication.JwtBearer NuGet

Quick Start

using RepletoryLib.Auth.Jwt;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRepletoryJwt(builder.Configuration);

var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
{
  "Jwt": {
    "Secret": "your-256-bit-secret-key-here-replace-in-production",
    "Issuer": "MyApp",
    "Audience": "MyApp.Users",
    "ExpiryMinutes": 30,
    "RefreshTokenExpiryDays": 7,
    "EnableRevocation": true
  }
}

Configuration

JwtOptions

Property Type Default Description
Secret string "" HMAC-SHA256 signing key (min 32 chars)
Issuer string "" Token issuer claim
Audience string "" Token audience claim
ExpiryMinutes int 30 Access token lifetime
RefreshTokenExpiryDays int 7 Refresh token lifetime
EnableRevocation bool true Enable token blacklisting

Usage Examples

Generating Tokens

using RepletoryLib.Auth.Jwt.Interfaces;
using RepletoryLib.Auth.Jwt.Models;

public class AuthController : ControllerBase
{
    private readonly IJwtService _jwt;

    public AuthController(IJwtService jwt) => _jwt = jwt;

    [HttpPost("login")]
    public IActionResult Login(LoginRequest request)
    {
        var user = _userService.Authenticate(request.Email, request.Password);
        if (user is null) return Unauthorized();

        var token = _jwt.GenerateToken(new JwtTokenRequest
        {
            UserId = user.Id.ToString(),
            UserName = user.FullName,
            Email = user.Email,
            Roles = user.Roles.Select(r => r.Name).ToList(),
            TenantId = user.TenantId,
            CustomClaims = new Dictionary<string, string>
            {
                ["department"] = user.Department
            }
        });

        return Ok(token);
        // { "accessToken": "eyJ...", "refreshToken": "abc123...", "expiresAt": "...", "tokenType": "Bearer" }
    }
}

Refresh Token Flow

[HttpPost("refresh")]
public async Task<IActionResult> Refresh([FromBody] RefreshRequest request)
{
    var result = await _jwt.RefreshToken(request.RefreshToken);

    if (!result.IsSuccess)
        return Unauthorized(result.Error);

    return Ok(result.Data);
}

Token Revocation

[Authorize]
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
    var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
    await _jwt.RevokeToken(token);
    return NoContent();
}

Accessing Current User

AddRepletoryJwt registers ICurrentUserService which extracts user context from JWT claims:

using RepletoryLib.Common.Interfaces;

public class OrderService
{
    private readonly ICurrentUserService _user;

    public OrderService(ICurrentUserService user) => _user = user;

    public async Task CreateOrderAsync(Order order)
    {
        order.CreatedBy = _user.UserId;
        order.TenantId = _user.TenantId;

        if (!_user.HasPermission("orders.create"))
            throw new AppException("Forbidden", 403);

        var roles = _user.Roles; // ["Admin", "Manager"]
    }
}

Integration with Other RepletoryLib Packages

Package Relationship
RepletoryLib.Common ICurrentUserService, Result<T>
RepletoryLib.Caching.Abstractions Token blacklist stored in ICacheService
RepletoryLib.Auth.Permissions Permission-based authorization on top of JWT
RepletoryLib.Api.Swagger JWT auth button in Swagger UI
RepletoryLib.Logging UserContextEnricher uses ICurrentUserService
RepletoryLib.Data.Interceptors AuditInterceptor uses ICurrentUserService for audit fields

Testing

Use MockCurrentUserService from RepletoryLib.Testing:

using RepletoryLib.Testing;

public class OrderServiceTests : TestBase
{
    [Fact]
    public async Task CreateOrder_stamps_user_id()
    {
        Setup();
        MockUser.UserId = "user-123";
        MockUser.TenantId = Guid.NewGuid();
        Services.AddTransient<OrderService>();

        var service = BuildServiceProvider().GetRequiredService<OrderService>();
        var order = new Order();
        await service.CreateOrderAsync(order);

        order.CreatedBy.Should().Be("user-123");
    }
}

Troubleshooting

Issue Solution
401 on valid token Verify Secret, Issuer, and Audience match between token generation and validation
Refresh token fails Check that ICacheService is registered (Redis or InMemory)
ICurrentUserService returns empty Ensure UseAuthentication() is called before UseAuthorization() in middleware pipeline
Token not revoked Ensure EnableRevocation is true and ICacheService is properly configured

License

This project is licensed under the MIT License.

Copyright (c) 2024-2026 Repletory.


For complete documentation, infrastructure setup, and configuration reference, see the RepletoryLib main repository.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 72 3/2/2026