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 465 12/11/2025
1.8.0 382 11/13/2025
1.8.0-b211.72089fd9 242 11/12/2025
1.7.4 2,912 8/6/2025
1.7.3 234 8/2/2025
1.7.2 2,672 3/16/2025
1.7.1 1,204 12/12/2024
1.7.0 3,346 11/12/2024
1.6.6 1,066 11/8/2024
1.6.5 3,766 8/31/2024
1.6.4 743 8/2/2024
1.6.3 2,002 5/15/2024
1.6.2 743 2/16/2024
1.6.1 5,734 1/5/2024
1.6.0 2,286 11/30/2023
1.5.10-b186.aca976b4 147 11/30/2023
1.5.9 376 11/29/2023
1.5.9-b174.64153841 143 11/23/2023
1.5.9-b172.dfc6e7bd 110 11/17/2023
1.5.9-b171.4e2b92e2 143 11/4/2023
1.5.8 931 10/23/2023
1.5.7 9,186 7/31/2023
1.5.6 4,676 7/13/2023
1.5.5 490 6/29/2023
1.5.4 1,482 3/7/2023
1.5.3 703 3/3/2023
1.5.2 906 1/11/2023
1.5.2-b92.7c961f5f 248 1/11/2023
1.5.0 1,213 11/9/2022
1.5.0-b88.7a7c20cd 236 11/9/2022
1.4.7 5,165 10/20/2022
1.4.6 1,843 10/17/2022
1.4.5 1,958 10/1/2022
1.4.4 1,985 8/16/2022
1.4.3 2,186 8/2/2022
1.4.2 1,982 7/19/2022
1.4.2-b80.7fdbfd04 265 7/19/2022
1.4.2-b74.acaf86f5 267 6/15/2022
1.4.1 2,107 6/13/2022
1.4.0 1,856 6/6/2022
1.3.8 3,055 4/12/2022
1.3.7 1,839 3/21/2022
1.3.6 1,842 3/17/2022
1.3.6-b67.ca5053f3 302 3/16/2022
1.3.6-b66.4a9683e6 263 3/16/2022

net10.0 support