Mes authorizer is middle-ware to verify authencation of MesAuth service
$ dotnet add package MesAuth.AuthorizerEnterprise-grade Authentication & Authorization middleware for MES Vietnam Fully supports .NET 8 · .NET 9 · .NET 10 · JWT · Key Rotation · Refresh Token · Permission-based · Multi-tenant
/.well-known/jwks.json now returns a JWKS Set { "keys": [...] } array instead of a single JsonWebKey object. DiscoveryConfig.JsonWebKey is replaced by DiscoveryConfig.SigningKeys (IList<SecurityKey>).IssuerSigningKeyResolver is used instead of a static IssuerSigningKey. All active + grace-period keys are accepted simultaneously.OnAuthenticationFailed automatically calls DiscoveryService.RefreshAsync() and retries validation when a SecurityTokenSignatureKeyNotFoundException is raised — zero downtime during rotation.MesAuth.SslTrustHelper (AddTrustedDomains(params string[])) instead of inline config.TenantId claim){ "keys": [...] } array; DiscoveryConfig.SigningKeys replaces JsonWebKey; IssuerSigningKeyResolver handles multi-key validation; OnAuthenticationFailed auto-refreshes JWKS and retries on SecurityTokenSignatureKeyNotFoundException. JWKS cache reduced to 5 minutes.MesAuth.SslTrustHelper with multi-domain support via AddTrustedDomains(params string[]).# .NET 8+
dotnet add package MesAuth.Authorizer
builder.Services.AddMesAuth(options =>
{
options.AppId = "your-app-id";
options.AppKey = "your-app-key";
options.WellknowConfigUri = "https://your-auth-server/.well-known/openid-configuration";
options.AutoRegisterEndpoints = false; // Set to true to auto-register auth endpoints
});
// In your middleware pipeline
app.UseMesAuth();
For routes that should bypass authentication (like error pages):
app.MapGet("/", () => Results.Ok(new { message = "This is exception page" }))
.MesAuthException();
// Check permissions in your endpoints
app.MapGet("/api/data", async (HttpContext context) =>
{
var user = context.GetUser();
if (user?.Perms?.Contains("read:data") != true)
return Results.Forbid();
return Results.Ok("Authorized data");
});
// Get current user information
var user = context.GetUser();
if (user != null)
{
var userId = user.UserId;
var fullName = user.FullName;
var permissions = user.Perms;
}
// Inject the notification service
private readonly ClientNotificationService _notificationService;
public MyController(ClientNotificationService notificationService)
{
_notificationService = notificationService;
}
// Send notifications
await _notificationService.SendNotificationAsync(userId, "Your message here");
// Use HttpContext extensions for centralized audit logging
await context.LogInfo(ClientLogCategory.SystemEvent, "User uploaded file: {fileName}", fileName);
await context.LogError(ClientLogCategory.Security, "Failed login attempt for user: {userName}", userName);
// Available categories:
// - ClientLogCategory.SystemEvent
// - ClientLogCategory.Authorization
// - ClientLogCategory.Authentication
// - ClientLogCategory.Security
Contributions are welcome! Please feel free to submit a Pull Request.