CerbiShield.Authentication-Shared
1.2.0
dotnet add package CerbiShield.Authentication-Shared --version 1.2.0
NuGet\Install-Package CerbiShield.Authentication-Shared -Version 1.2.0
<PackageReference Include="CerbiShield.Authentication-Shared" Version="1.2.0" />
<PackageVersion Include="CerbiShield.Authentication-Shared" Version="1.2.0" />
<PackageReference Include="CerbiShield.Authentication-Shared" />
paket add CerbiShield.Authentication-Shared --version 1.2.0
#r "nuget: CerbiShield.Authentication-Shared, 1.2.0"
#:package CerbiShield.Authentication-Shared@1.2.0
#addin nuget:?package=CerbiShield.Authentication-Shared&version=1.2.0
#tool nuget:?package=CerbiShield.Authentication-Shared&version=1.2.0
CerbiShield.Authentication-Shared
A robust, configuration-driven JWT authentication library for ASP.NET Core applications with multi-audience support and deterministic app context resolution.
Version: 1.2.0 | Target Framework: .NET 8.0
What's New in 1.2.0
- Multi-audience validation: Automatically validates tokens with GUID or
api://GUIDformat audiences - App context resolution: Deterministic resolution from headers, claims, or configuration
- App context middleware:
UseCerbiAppContext()with fail-fast 400 responses - Enhanced diagnostics: Detailed logging of audience/issuer mismatches
- Diagnostics endpoint: Optional
/api/system/whoamiendpoint helper
Migration from 1.0.2/1.1.x
Required Changes
Add the
X-Cerbi-Appheader to all API requests (sent by your router/gateway):X-Cerbi-App: your-app-nameAdd new environment variables (optional but recommended):
# If your audience is a GUID, both formats are auto-supported: JWT__Audience=12345678-1234-1234-1234-123456789012 # Or explicitly add additional audiences: JWT__AdditionalAudiences=api://your-app,https://your-api.comUpdate your Program.cs to include app context middleware:
app.UseAuthentication(); app.UseCerbiAppContext(); // NEW - add after UseAuthentication app.UseAuthorization();
Breaking Changes
IdentityProviderOptions.AdditionalAudiencesis a new property (List<string>)- App context is now required by default (set
IdentityProvider:RequireAppContext=falseto disable)
Installation
dotnet add package CerbiShield.Authentication-Shared --version 1.2.0
Quick Start
1. Configure appsettings.json
{
"JWT": {
"Authority": "https://login.microsoftonline.com/{tenant-id}/v2.0",
"Audience": "12345678-1234-1234-1234-123456789012"
},
"IdentityProvider": {
"AppContextHeader": "X-Cerbi-App",
"RequireAppContext": true
}
}
2. Configure Program.cs
using CerbiShield.Authentication.Extensions;
using CerbiShield.Authentication.Middleware;
using CerbiShield.Authentication.Diagnostics;
var builder = WebApplication.CreateBuilder(args);
// Register IConfiguration (required)
builder.Services.AddSingleton<IConfiguration>(builder.Configuration);
// Add CerbiShield JWT authentication with multi-audience support
builder.Services.AddCerbiJwtAuthentication(builder.Configuration);
builder.Services.AddControllers();
var app = builder.Build();
// Middleware order is important!
app.UseAuthentication();
app.UseCerbiAppContext(); // Resolves and validates app context
app.UseAuthorization();
// Optional: Add diagnostics endpoint
app.MapCerbiWhoAmI(); // Maps /api/system/whoami
app.MapControllers();
app.Run();
Features
Multi-Audience JWT Validation
Tokens from different sources (MSAL, Azure CLI, etc.) may have different audience formats:
| Source | Audience Format |
|---|---|
| MSAL | api://12345678-... |
| Azure CLI | 12345678-... (GUID only) |
CerbiShield automatically validates both formats when you configure a GUID audience:
{
"JWT": {
"Audience": "12345678-1234-1234-1234-123456789012"
}
}
This automatically allows:
12345678-1234-1234-1234-123456789012api://12345678-1234-1234-1234-123456789012
App Context Resolution
App context is resolved deterministically in this order:
X-Cerbi-Appheader (canonical - highest priority)- Configured
AppClaimfrom token (default:app) azpclaim (OAuth2 authorized party)appidclaim (Azure AD v1)- Route value
appName DefaultAppNameconfig (dev/test only)
// Access the resolved app context in your controller:
var appName = HttpContext.Items["CerbiApp"] as string;
// Or inject IAppContextResolver for detailed info:
public class MyController : ControllerBase
{
private readonly IAppContextResolver _appResolver;
public MyController(IAppContextResolver appResolver)
{
_appResolver = appResolver;
}
[HttpGet]
public IActionResult Get()
{
var result = _appResolver.ResolveWithDetails(HttpContext);
// result.AppName, result.Source, result.DiagnosticMessage
}
}
App Context Middleware
The middleware validates app context and returns 400 if not resolved:
{
"error": "app_context_required",
"message": "Application context could not be resolved. Please include the 'X-Cerbi-App' header.",
"correlationId": "abc123",
"details": {
"headerExpected": "X-Cerbi-App",
"resolutionAttempts": ["..."]
}
}
To disable (not recommended for production):
{
"IdentityProvider": {
"RequireAppContext": false
}
}
Configuration Reference
JWT Settings
| Key | Description | Default |
|---|---|---|
JWT:Authority |
OIDC authority URL | Required |
JWT:Audience |
Primary audience (GUID or api://GUID) | Required |
JWT:AdditionalAudiences |
Comma-separated additional audiences | |
JWT:ValidIssuers |
Comma-separated valid issuers | Authority |
JWT:RequireHttpsMetadata |
Require HTTPS for metadata | true |
JWT:SaveToken |
Save token on auth ticket | false |
IdentityProvider Settings
| Key | Description | Default |
|---|---|---|
IdentityProvider:AppContextHeader |
Header name for app context | X-Cerbi-App |
IdentityProvider:RequireAppContext |
Require app context (400 if missing) | true |
IdentityProvider:DefaultAppName |
Default app name (dev only) | |
IdentityProvider:AppClaim |
Token claim for app name | app |
IdentityProvider:RoleClaim |
Token claim for roles | roles |
IdentityProvider:ScopeClaim |
Token claim for scopes | scp |
Diagnostics
Startup Logs
========== CerbiShield JWT Authentication Configuration (v1.2.0) ==========
[JWT Config] Provider=Entra ID (Azure AD) Authority=https://login.microsoftonline.com/tenant/v2.0
[JWT Config] ValidAudiences (2): 12345678-... | api://12345678-...
[App Context] Header=X-Cerbi-App RequireAppContext=True DefaultAppName=(not set)
==========================================================================
Authentication Failure Logs
JWT authentication FAILED. Reason=Invalid audience: 'wrong-audience'
[AUTH DIAGNOSTIC] Allowed audiences: 12345678-..., api://12345678-...
License
MIT
| 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.15)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.IdentityModel.JsonWebTokens (>= 7.5.1)
- Microsoft.IdentityModel.Protocols (>= 7.5.1)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 7.5.1)
- Microsoft.IdentityModel.Tokens (>= 7.5.1)
- System.IdentityModel.Tokens.Jwt (>= 7.5.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.