A library that provides everything the standard JWT Bearer authentication offers, with the added power of built-in DPoP (Demonstration of Proof-of-Possession) support for enhanced token security. Simplify your Auth0 JWT authentication integration for ASP.NET Core APIs with Auth0-specific configuration and validation.
- Features
- Requirements
- Installation
- Migration from JWT Bearer
- Getting Started
- DPoP: Enhanced Token Security
- Advanced Features
- Examples
- Development
- Contributing
- Support
- License
This library builds on top of the standard Microsoft.AspNetCore.Authentication.JwtBearer package, providing:
- Complete JWT Bearer Functionality - All features from
Microsoft.AspNetCore.Authentication.JwtBearerare available - Built-in DPoP Support - Industry-leading proof-of-possession token security per RFC 9449
- Auth0 Optimized - Pre-configured for Auth0's authentication patterns
- Zero Lock-in - Use standard JWT Bearer features alongside DPoP enhancements
- Single Package - Everything you need in one dependency
- Flexible Configuration - Options pattern with full access to underlying JWT Bearer configuration
- This library currently supports .NET 8.0 and above.
Install the package via NuGet Package Manager:
dotnet add package Auth0.AspNetCore.Authentication.ApiOr via the Package Manager Console:
Install-Package Auth0.AspNetCore.Authentication.ApiAlready using Microsoft.AspNetCore.Authentication.JwtBearer? Great news! This library is a drop-in replacement with zero behavior changes.
Migrating from JWT Bearer is simple:
Before:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
options.Audience = builder.Configuration["Auth0:Audience"];
});After:
builder.Services.AddAuth0ApiAuthentication(options =>
{
options.Domain = builder.Configuration["Auth0:Domain"];
options.JwtBearerOptions = new JwtBearerOptions
{
Audience = builder.Configuration["Auth0:Audience"]
};
});Zero Breaking Changes - All JWT Bearer functionality works identically
5-15 Lines - Typically only 5-15 lines of code change
Full Compatibility - Custom events, validation, and policies work as-is
New Capabilities - Optional DPoP support with zero refactoring
For detailed migration instructions including:
- 8 migration scenarios (basic to complex)
- Custom events and validation
- Multiple audiences
- Testing strategies
- Rollback procedures
- Troubleshooting (10+ common issues)
See the Complete Migration Guide
Add Auth0 authentication to your ASP.NET Core API in Program.cs:
using Auth0.AspNetCore.Authentication.Api;
using Microsoft.AspNetCore.Authentication.JwtBearer;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Adds Auth0 JWT validation to the API
builder.Services.AddAuth0ApiAuthentication(options =>
{
options.JwtBearerOptions = new JwtBearerOptions
{
Audience = builder.Configuration["Auth0:Audience"]
};
});
builder.Services.AddAuthorization();
WebApplication app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/open-endpoint", () =>
{
var responseMessage = "This endpoint is available to all users.";
return responseMessage;
})
.WithName("AccessOpenEndpoint")
.WithOpenApi();
app.MapGet("/restricted-endpoint", () =>
{
var responseMessage = "This endpoint is available only to authenticated users.";
return responseMessage;
})
.WithName("AccessRestrictedEndpoint")
.WithOpenApi().RequireAuthorization();
app.Run();Want more examples? Check out EXAMPLES.md for comprehensive code examples including authorization policies, scopes, permissions, custom handlers, and more!
Add the following settings to your appsettings.json:
{
"Auth0": {
"Domain": "your-tenant.auth0.com",
"Audience": "https://your-api-identifier"
}
}Required Settings:
- Domain: Your Auth0 domain (e.g.,
my-app.auth0.com) - without thehttps://prefix - Audience: The API identifier configured in your Auth0 Dashboard
The library automatically constructs the authority URL as https://{Domain}.
DPoP (Demonstration of Proof-of-Possession) is a security mechanism that binds access tokens to a cryptographic key, making them resistant to token theft and replay attacks. This library provides seamless DPoP integration for your Auth0-protected APIs.
Learn more about DPoP: Auth0 DPoP Documentation
Enable DPoP with a single method call:
builder.Services.AddAuth0ApiAuthentication(options =>
{
options.Domain = builder.Configuration["Auth0:Domain"];
options.JwtBearerOptions = new JwtBearerOptions
{
Audience = builder.Configuration["Auth0:Audience"]
};
}).WithDPoP(); // Enable DPoP supportThat's it! Your API now supports DPoP tokens while maintaining backward compatibility with Bearer tokens.
For fine-grained control, configure DPoP behavior:
builder.Services.AddAuth0ApiAuthentication(options =>
{
options.Domain = builder.Configuration["Auth0:Domain"];
options.JwtBearerOptions = new JwtBearerOptions
{
Audience = builder.Configuration["Auth0:Audience"]
};
}).WithDPoP(dpopOptions =>
{
// Enforcement mode
dpopOptions.Mode = DPoPModes.Required;
// Time validation settings
dpopOptions.IatOffset = 300; // Allow 300 seconds offset for 'iat' claim (default)
dpopOptions.Leeway = 30; // 30 seconds leeway for time-based validation (default)
});Choose the right enforcement mode for your security requirements:
| Mode | Description |
|---|---|
DPoPModes.Allowed (default) |
Accept both DPoP and Bearer tokens |
DPoPModes.Required |
Only accept DPoP tokens, reject Bearer tokens |
DPoPModes.Disabled |
Standard JWT Bearer validation only |
Learn more: See detailed DPoP examples and use cases in EXAMPLES.md
Since this library provides complete access to JWT Bearer configuration, you can use any standard JWT Bearer option:
builder.Services.AddAuth0ApiAuthentication(options =>
{
options.Domain = builder.Configuration["Auth0:Domain"];
options.JwtBearerOptions = new JwtBearerOptions
{
Audience = builder.Configuration["Auth0:Audience"],
// All standard JWT Bearer options are available
RequireHttpsMetadata = true,
SaveToken = true,
IncludeErrorDetails = true,
// Custom token validation parameters
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5),
NameClaimType = ClaimTypes.NameIdentifier
},
// Event handlers for custom logic
Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Console.WriteLine($"Authentication failed: {context.Exception.Message}");
return Task.CompletedTask;
}
}
};
});Looking for more advanced scenarios? Visit EXAMPLES.md for examples on:
- Scope and permission-based authorization
- Custom authorization handlers
- Role-based access control
- Custom JWT Bearer events
- SignalR integration
- Error handling and logging
- And much more!
For comprehensive, copy-pastable code examples covering various scenarios, see EXAMPLES.md:
- Getting Started - Basic authentication and endpoint protection
- Configuration - Custom token validation and settings
- DPoP - All DPoP modes with practical examples
- Authorization - Scopes, permissions, roles, and custom handlers
- Advanced Scenarios - Claims, events, custom error responses
- Integration - SignalR and other integrations
Clone the repository and build the solution:
git clone https://github.com/auth0/aspnetcore-api.git
cd aspnetcore-api
dotnet restore Auth0.AspNetCore.Authentication.Api.sln
dotnet build Auth0.AspNetCore.Authentication.Api.sln --configuration ReleaseRun the unit test suite:
dotnet test tests/Auth0.AspNetCore.Authentication.Api.UnitTests/The repository includes a playground application for testing both standard JWT Bearer and DPoP authentication:
-
Configure Auth0 settings in
Auth0.AspNetCore.Authentication.Api.Playground/appsettings.json:{ "Auth0": { "Domain": "your-tenant.auth0.com", "Audience": "https://your-api-identifier" } } -
Run the playground:
cd Auth0.AspNetCore.Authentication.Api.Playground dotnet run -
Access the application:
- Swagger UI:
https://localhost:7190/swagger - Open endpoint: GET
/open-endpoint(no authentication required) - Protected endpoint: GET
/restricted-endpoint(requires authentication)
- Swagger UI:
The playground includes a pre-configured Postman collection (Auth0.AspNetCore.Authentication.Api.Playground.postman_collection.json) with ready-to-use requests:
- Import the collection into Postman
- Obtain a JWT token from Auth0
- Set the
{{token}}variable in your Postman environment - Test both endpoints with pre-configured headers
See the Playground README for detailed testing instructions and examples.
We appreciate your contributions! Please review our contribution guidelines before submitting pull requests.
- ✅ Read the Auth0 General Contribution Guidelines
- ✅ Read the Auth0 Code of Conduct
- ✅ Ensure all tests pass
- ✅ Add tests for new functionality
- ✅ Update documentation as needed
- ✅ Sign all commits
If you have questions or need help:
- 📖 Check the Auth0 Documentation
- � See EXAMPLES.md for code examples
- 💬 Visit the Auth0 Community
- 🐛 Report issues on GitHub Issues
Copyright 2025 Okta, Inc.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Auth0 is an easy-to-implement, adaptable authentication and authorization platform. To learn more check out Why Auth0?
This project is licensed under the Apache License 2.0. See the LICENSE file for more info.
