Plinth.Security.Jwt 1.8.1

Prefix Reserved
dotnet add package Plinth.Security.Jwt --version 1.8.1
                    
NuGet\Install-Package Plinth.Security.Jwt -Version 1.8.1
                    
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="Plinth.Security.Jwt" Version="1.8.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Plinth.Security.Jwt" Version="1.8.1" />
                    
Directory.Packages.props
<PackageReference Include="Plinth.Security.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 Plinth.Security.Jwt --version 1.8.1
                    
#r "nuget: Plinth.Security.Jwt, 1.8.1"
                    
#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 Plinth.Security.Jwt@1.8.1
                    
#: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=Plinth.Security.Jwt&version=1.8.1
                    
Install as a Cake Addin
#tool nuget:?package=Plinth.Security.Jwt&version=1.8.1
                    
Install as a Cake Tool

README

Plinth.Security.Jwt

JWT signing and encryption utilities, add-on to Plinth.Security

Provides utilities for creating, validating, and refreshing JWTs with support for both signed (JWS) and encrypted (JWE) tokens.

  • Supports Signed JWT (JWS) via
    • HMAC with SHA-{256, 384, 512}
    • RSA with SHA-{256, 384, 512}
  • Supports Encrypted JWT (JWE) via
    • AES-{128, 192, 256}-CBC-HMAC-{256, 384, 512}
    • RSA-OAEP-{160, 256, 384, 512} with AES-{128, 192, 256}-CBC-HMAC-{256, 384, 512}

Setup

1. Install the Package

dotnet add package Plinth.Security.Jwt

2. Configure JWT Options

Create and configure JwtGenerationOptions with your desired security mode:

using Plinth.Security.Jwt;

// Example using HMAC signature (symmetric key)
var secretKey = new byte[32]; // 32 bytes = 256 bits for HS256
// ... populate secretKey from secure configuration ...

var jwtOptions = new JwtGenerationOptions
{
    SecurityMode = new JwtSecurityModeHmacSignature(secretKey),
    Issuer = "MyApplication",
    Audience = "MyApplicationUsers",
    TokenLifetime = TimeSpan.FromMinutes(15),
    MaxTokenLifetime = TimeSpan.FromHours(24),
    TokenContentLogging = false // Set to true only in development
};

jwtOptions.Validate();

3. Register with Dependency Injection

services.AddSingleton(jwtOptions);
services.AddSingleton<JwtValidator>();
services.AddSingleton<JwtGenerator>();

Usage

Creating JWTs

Use JwtGenerator to create tokens for authenticated users:

public class AuthController : Controller
{
    private readonly JwtGenerator _jwtGenerator;

    public AuthController(JwtGenerator jwtGenerator)
    {
        _jwtGenerator = jwtGenerator;
    }

    [HttpPost("login")]
    public async Task<ActionResult> Login([FromBody] LoginRequest request)
    {
        // ... validate credentials ...

        var userId = Guid.NewGuid(); // from your user database
        var userName = "user@example.com";
        var roles = new[] { "User", "Admin" };

        // Create a JWT with basic user information
        var jwtData = _jwtGenerator.GetBuilder(userId, userName, roles)
            .Build();

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

Adding Custom Claims

You can add custom claims to the JWT:

var jwtData = _jwtGenerator.GetBuilder(userId, userName, roles)
    .AddClaim("department", "Engineering")
    .AddClaim("employee_id", "12345")
    .Build();

Validating JWTs

Use JwtValidator to validate and extract claims from tokens:

public class SecureController : Controller
{
    private readonly JwtValidator _jwtValidator;

    public SecureController(JwtValidator jwtValidator)
    {
        _jwtValidator = jwtValidator;
    }

    [HttpGet("secure-data")]
    public ActionResult GetSecureData([FromHeader(Name = "Authorization")] string authHeader)
    {
        try
        {
            var token = authHeader.Replace("Bearer ", "");
            var claimsPrincipal = _jwtValidator.Validate(token);

            var userId = claimsPrincipal.JwtUserId();
            var userName = claimsPrincipal.JwtUserName();
            var roles = claimsPrincipal.JwtRoles();

            // ... use claims to authorize and fetch data ...

            return Ok();
        }
        catch (SecurityTokenException ex)
        {
            return Unauthorized(new { error = "Invalid token" });
        }
    }
}

Refreshing Tokens

Refresh an existing token to extend its lifetime (up to MaxTokenLifetime):

[HttpPost("refresh")]
public ActionResult RefreshToken([FromBody] RefreshRequest request)
{
    try
    {
        var newJwtData = _jwtGenerator.Refresh(request.Token);
        return Ok(new { token = newJwtData.Token });
    }
    catch (SecurityTokenExpiredException)
    {
        return Unauthorized(new { error = "Token has reached maximum lifetime" });
    }
}

Security Modes

HMAC Signature (Symmetric)

Use for single-server or shared-secret scenarios:

var secretKey = new byte[32]; // 32 bytes for HS256, 48 for HS384, 64 for HS512
// Load from secure configuration (e.g., Azure Key Vault, environment variable)

var securityMode = new JwtSecurityModeHmacSignature(secretKey);

RSA Signature (Asymmetric)

Use for distributed systems where token validation occurs on different servers:

using System.Security.Cryptography;

var rsa = RSA.Create(2048); // 2048-bit key
// Or load from certificate store

var securityMode = new JwtSecurityModeRsaSignature(rsa, SecurityAlgorithms.RsaSha256);

AES Encryption (Symmetric)

Use when token contents must be encrypted:

var encryptionKey = new byte[32]; // 32 bytes for AES256
// Load from secure configuration

var securityMode = new JwtSecurityModeAesEncryption(encryptionKey);

RSA Encryption (Asymmetric)

Use for encrypted tokens in distributed systems:

var rsa = RSA.Create(2048);
// Or load from certificate store

var securityMode = new JwtSecurityModeRsaEncryption(rsa);

ClaimsPrincipal Extension Methods

The library provides extension methods for extracting JWT claims:

  • JwtUserId() - Get the user's unique identifier (Guid)
  • JwtUserName() - Get the user's unique name/email
  • JwtRoles() - Get the user's roles as an array
  • JwtSessionGuid() - Get the session identifier
  • JwtOriginalIssue() - Get the original issue date (for refresh tracking)

Best Practices

  1. Secure Key Storage: Store encryption/signing keys in secure configuration (Azure Key Vault, AWS Secrets Manager, etc.)
  2. Short Token Lifetimes: Keep TokenLifetime short (5-15 minutes) and use refresh tokens
  3. Disable Logging in Production: Set TokenContentLogging = false in production to avoid leaking sensitive data
  4. HTTPS Only: Always transmit JWTs over HTTPS
  5. Validate on Every Request: Always validate tokens on protected endpoints
  6. Use Strong Keys: Use at least 256-bit keys for HMAC, 2048-bit for RSA
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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 (1)

Showing the top 1 NuGet packages that depend on Plinth.Security.Jwt:

Package Downloads
Plinth.AspNetCore

Plinth ASP.NET Core Services Utilities

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.8.1 2,718 12/11/2025
1.8.0 728 11/13/2025
1.8.0-b211.72089fd9 269 11/12/2025
1.7.4 5,473 8/6/2025
1.7.3 280 8/2/2025
1.7.2 3,307 3/16/2025
1.7.1 1,341 12/12/2024
1.7.0 6,250 11/12/2024
1.6.6 1,103 11/8/2024
1.6.5 3,813 8/31/2024
1.6.4 781 8/2/2024
1.6.3 2,033 5/15/2024
1.6.2 783 2/16/2024
1.6.1 6,120 1/5/2024
1.6.0 2,310 11/30/2023
1.5.10-b186.aca976b4 175 11/30/2023
1.5.9 396 11/29/2023
1.5.9-b174.64153841 165 11/23/2023
1.5.9-b172.dfc6e7bd 131 11/17/2023
1.5.9-b171.4e2b92e2 167 11/4/2023
Loading failed

net10.0 support