POC.Identity.Security.JWT.Validator 1.0.1

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

POC.Identity.Security.JWT.Validator

NuGet License: MIT

JWT Token Validator and Claims Extractor for applications consuming the POC.Identity API.

Validates JWT tokens (ES256) using JWKS endpoint, extracts user information, permissions, and roles. Designed to work seamlessly with POC.Identity.Security.JWT package.


?? Features

? JWT Token Validation - Validates ES256 tokens using JWKS endpoint
? Claims Extraction - Extracts user ID, type, name, permissions, and roles
? JWKS Integration - Automatically fetches and caches public keys
? Permission Checks - Built-in methods to verify permissions and roles
? Memory Cache - Caches JWKS keys to reduce API calls
? Expiration Checks - Verifies token expiration and provides warning
? Easy Configuration - Simple setup via appsettings.json
? .NET 8 Ready - Built for .NET 8 with nullable reference types


?? Installation

dotnet add package POC.Identity.Security.JWT.Validator

Or via NuGet Package Manager:

Install-Package POC.Identity.Security.JWT.Validator

?? Quick Start

1. Configure in appsettings.json

{
  "JwtValidation": {
    "Authority": "https://your-identity-api.com",
    "JwksEndpoint": "https://your-identity-api.com/jwks",
    "ValidIssuer": "POC.Identity.API",
    "ValidAudience": "POC.Identity.Clients",
    "ValidateIssuer": true,
    "ValidateAudience": true,
    "ValidateLifetime": true,
    "ValidateIssuerSigningKey": true,
    "ClockSkewMinutes": 5,
    "JwksCacheMinutes": 60,
    "HttpTimeoutSeconds": 30
  }
}

2. Register Services in Program.cs

using POC.Identity.Security.JWT.Validator.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add JWT Validator
builder.Services.AddJwtValidation(builder.Configuration);

var app = builder.Build();
app.Run();

3. Use in Your Code

using POC.Identity.Security.JWT.Validator.Services;

public class MyService
{
    private readonly IJwtValidatorService _jwtValidator;

    public MyService(IJwtValidatorService jwtValidator)
    {
        _jwtValidator = jwtValidator;
    }

    public async Task<bool> ValidateUserToken(string token)
    {
        var result = await _jwtValidator.ValidateTokenAsync(token);

        if (result.IsValid)
        {
            var tokenInfo = result.TokenInfo;
            Console.WriteLine($"User: {tokenInfo.Name}");
            Console.WriteLine($"UserId: {tokenInfo.UserId}");
            Console.WriteLine($"Permissions: {string.Join(", ", tokenInfo.Permissions)}");
            Console.WriteLine($"Roles: {string.Join(", ", tokenInfo.Roles)}");

            // Check permissions
            if (tokenInfo.HasPermission("users.write"))
            {
                Console.WriteLine("User can write users");
            }

            // Check roles
            if (tokenInfo.HasRole("Admin"))
            {
                Console.WriteLine("User is admin");
            }

            return true;
        }
        else
        {
            Console.WriteLine($"Validation failed: {result.ErrorMessage}");
            Console.WriteLine($"Error code: {result.ErrorCode}");
            return false;
        }
    }
}

?? Usage Examples

Validate Token

var result = await _jwtValidator.ValidateTokenAsync(token);

if (result.IsValid)
{
    var info = result.TokenInfo;
    // Token is valid, use info
}
else
{
    // Handle error
    Console.WriteLine($"Error: {result.ErrorMessage}");
    Console.WriteLine($"Code: {result.ErrorCode}");
}

Extract Token Info Without Validation

Useful to quickly check token data before validation:

var tokenInfo = _jwtValidator.ExtractTokenInfoWithoutValidation(token);

if (tokenInfo != null)
{
    Console.WriteLine($"User: {tokenInfo.Name}");
    Console.WriteLine($"Expires: {tokenInfo.ExpiresAt}");
}

Check Token Expiration

bool isExpired = _jwtValidator.IsTokenExpired(token);

if (isExpired)
{
    Console.WriteLine("Token has expired");
}

Check Permissions

// Single permission
if (tokenInfo.HasPermission("users.write"))
{
    // User can write users
}

// Any permission
if (tokenInfo.HasAnyPermission("users.write", "users.delete"))
{
    // User has at least one permission
}

// All permissions
if (tokenInfo.HasAllPermissions("users.read", "users.write"))
{
    // User has all permissions
}

Check Roles

// Single role
if (tokenInfo.HasRole("Admin"))
{
    // User is admin
}

// Any role
if (tokenInfo.HasAnyRole("Admin", "Manager"))
{
    // User has at least one role
}

Check Expiration Warning

if (tokenInfo.IsExpiringSoon(minutesBeforeExpiry: 10))
{
    Console.WriteLine("Token will expire in less than 10 minutes");
    // Show warning to user or refresh token
}

if (tokenInfo.IsExpired)
{
    Console.WriteLine("Token has expired");
    // Redirect to login
}

Refresh JWKS Keys

Force refresh of cached public keys:

await _jwtValidator.RefreshJwksKeysAsync();

?? Configuration Options

Property Type Default Description
Authority string - Identity API base URL
JwksEndpoint string - JWKS endpoint URL to fetch public keys
ValidIssuer string - Expected token issuer
ValidAudience string - Expected token audience
ValidateIssuer bool true Validate token issuer
ValidateAudience bool true Validate token audience
ValidateLifetime bool true Validate token expiration
ValidateIssuerSigningKey bool true Validate token signature
ClockSkewMinutes int 5 Clock skew tolerance (minutes)
JwksCacheMinutes int 60 JWKS cache duration (minutes)
HttpTimeoutSeconds int 30 HTTP request timeout (seconds)

?? TokenInfo Properties

public class TokenInfo
{
    public string UserId { get; set; }
    public string UserType { get; set; }
    public string Identifier { get; set; }
    public string Name { get; set; }
    public List<string> Permissions { get; set; }
    public List<string> Roles { get; set; }
    public List<ApplicationRole> Applications { get; set; }
    public DateTime IssuedAt { get; set; }
    public DateTime ExpiresAt { get; set; }
    public string Token { get; set; }
    
    // Helper methods
    public bool HasPermission(string permission);
    public bool HasAnyPermission(params string[] permissions);
    public bool HasAllPermissions(params string[] permissions);
    public bool HasRole(string role);
    public bool HasAnyRole(params string[] roles);
    public bool IsExpiringSoon(int minutesBeforeExpiry = 5);
    public bool IsExpired { get; }
}

? ValidationErrorCode Enum

public enum ValidationErrorCode
{
    None = 0,
    InvalidToken = 1,
    TokenExpired = 2,
    InvalidSignature = 3,
    InvalidIssuer = 4,
    InvalidAudience = 5,
    JwksUnavailable = 6,
    ValidationError = 7
}

??? Use Cases

ASP.NET Core Web App

// Program.cs
builder.Services.AddJwtValidation(builder.Configuration);

// Controller
public class HomeController : Controller
{
    private readonly IJwtValidatorService _validator;

    public HomeController(IJwtValidatorService validator)
    {
        _validator = validator;
    }

    public async Task<IActionResult> Index()
    {
        var token = HttpContext.Session.GetString("AccessToken");
        var result = await _validator.ValidateTokenAsync(token);

        if (!result.IsValid)
        {
            return RedirectToAction("Login", "Auth");
        }

        ViewBag.UserName = result.TokenInfo.Name;
        ViewBag.Permissions = result.TokenInfo.Permissions;
        
        return View();
    }
}

Middleware

public class JwtValidationMiddleware
{
    private readonly RequestDelegate _next;

    public JwtValidationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, IJwtValidatorService validator)
    {
        var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

        if (!string.IsNullOrEmpty(token))
        {
            var result = await validator.ValidateTokenAsync(token);

            if (result.IsValid)
            {
                context.Items["TokenInfo"] = result.TokenInfo;
                await _next(context);
                return;
            }
        }

        context.Response.StatusCode = 401;
        await context.Response.WriteAsync("Unauthorized");
    }
}

Razor Pages

public class IndexModel : PageModel
{
    private readonly IJwtValidatorService _validator;

    public IndexModel(IJwtValidatorService validator)
    {
        _validator = validator;
    }

    public string UserName { get; set; }
    public bool CanEdit { get; set; }

    public async Task<IActionResult> OnGetAsync()
    {
        var token = HttpContext.Session.GetString("AccessToken");
        var result = await _validator.ValidateTokenAsync(token);

        if (!result.IsValid)
        {
            return RedirectToPage("/Login");
        }

        UserName = result.TokenInfo.Name;
        CanEdit = result.TokenInfo.HasPermission("users.write");

        return Page();
    }
}

?? Integration with POC.Identity.Security.JWT

This package is designed to work with the POC.Identity.Security.JWT package:

  • API Side: Use POC.Identity.Security.JWT to generate ES256 tokens
  • Client Side: Use POC.Identity.Security.JWT.Validator to validate tokens
???????????????????????????????????????????????????????
?                  Identity API                       ?
?  (POC.Identity.Security.JWT)                        ?
?  - Generates ES256 JWT tokens                       ?
?  - Exposes JWKS endpoint (/jwks)                    ?
?  - Automatic key rotation                           ?
???????????????????????????????????????????????????????
                   ?
                   ? JWT Token
                   ?
                   ?
???????????????????????????????????????????????????????
?              Client Application                     ?
?  (POC.Identity.Security.JWT.Validator)              ?
?  - Validates JWT tokens                             ?
?  - Fetches public keys from JWKS                    ?
?  - Extracts user info and permissions               ?
?  - Caches keys for performance                      ?
???????????????????????????????????????????????????????


?? License

This project is licensed under the MIT License - see the LICENSE.txt file for details.


?? Issues & Contributions


?? Support

For questions or support, please open an issue on GitHub.


Made with ?? by POC Identity Team

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 was computed.  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 was computed.  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.1 184 11/5/2025