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
<PackageReference Include="POC.Identity.Security.JWT.Validator" Version="1.0.1" />
<PackageVersion Include="POC.Identity.Security.JWT.Validator" Version="1.0.1" />
<PackageReference Include="POC.Identity.Security.JWT.Validator" />
paket add POC.Identity.Security.JWT.Validator --version 1.0.1
#r "nuget: POC.Identity.Security.JWT.Validator, 1.0.1"
#:package POC.Identity.Security.JWT.Validator@1.0.1
#addin nuget:?package=POC.Identity.Security.JWT.Validator&version=1.0.1
#tool nuget:?package=POC.Identity.Security.JWT.Validator&version=1.0.1
POC.Identity.Security.JWT.Validator
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.JWTto generate ES256 tokens - Client Side: Use
POC.Identity.Security.JWT.Validatorto 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 ?
???????????????????????????????????????????????????????
?? Related Packages
- POC.Identity.Security.JWT - JWT token generator with ES256 and JWKS support (for API)
?? License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
?? Issues & Contributions
- Issues: GitHub Issues
- Pull Requests: Welcome!
?? Support
For questions or support, please open an issue on GitHub.
Made with ?? by POC Identity Team
| Product | Versions 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. |
-
net8.0
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.11)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Microsoft.IdentityModel.Tokens (>= 8.2.1)
- System.IdentityModel.Tokens.Jwt (>= 8.2.1)
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 |