Fast.JwtBearer
Public members, parameters, returns, and exceptions
Targets: net8.0;net9.0;net10.0.
Contract and constraints
JWT settings, authentication, authorization and token helpers. AddJwtBearerSetting configures utility options; AddJwtBearerAuthentication configures Bearer authentication; AddJwtBearer adds the framework authorization flow and discovered IJwtBearerHandle implementations. All default to JWTSettings. Issuer signing keys must be supplied externally and contain at least 32 UTF-8 bytes. Defaults include issuer Fast.NET.API, audience Fast.NET.Client, ClockSkew=5 seconds, access lifetime=20 minutes, refresh lifetime=1440 minutes, HS256 and RequireRefreshTokenCache=true. The memory distributed-cache fallback is process-local; multi-instance replay protection requires a shared atomic IRefreshTokenReplayStore. Fast.Cache supplies its Redis implementation. GenerateToken may add payload fields. Check IsValid after ValidateAsync; parsing a token alone is not authentication. Only issue tokens after the application has authenticated the subject. SignalR query-token extraction is restricted to recognized Hub endpoints.
Installation and examples
Install the package
dotnet add package Fast.JwtBearerExample 1
using Fast.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddJwtBearer(builder.Configuration);
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();Example 2
using Fast.JwtBearer;
public sealed record TokenPair(string AccessToken, string RefreshToken);
public sealed class TokenService
{
public TokenPair IssueForAuthenticatedUser(string subject)
{
ArgumentException.ThrowIfNullOrWhiteSpace(subject);
var payload = new Dictionary<string, object> { ["sub"] = subject };
string access = JwtBearerUtil.GenerateToken(payload, expiredTime: 20);
string refresh = JwtBearerUtil.GenerateRefreshToken(access);
return new TokenPair(access, refresh);
}
public async Task<bool> IsValidAsync(string token)
{
var result = await JwtBearerUtil.ValidateAsync(token);
return result.IsValid;
}
}Web-host examples belong in a consumer project using Microsoft.NET.Sdk.Web and a supported .NET target. IaaS examples can be used in an ordinary class library. Registration precedes builder.Build(); configure middleware and endpoints before app.Run(). Samples retain their original code and comments. No host, external service, database operation or client generator was run, and these snippets have not been compiled in this update.
Source reference
Composed authorization and replay protection
Only Fast-owned AppAuthorizeRequirement instances are certified by the Fast handler. Roles, claims, third-party policies and explicit failures remain independent; AllowForbidden bypasses only Fast permission checks. A nonempty Fast requirement without a custom handler is denied. Existing non-Fast policy-provider behavior and other handlers are retained.
Custom failure payloads never clear Fail(). Only MVC filter resources receive a JsonResult; endpoint middleware and SignalR handle their own denial responses.
AutoRefreshTokenAsync returning true means authorization may continue, not that a fresh token was always issued. Refresh updates the standard ClaimsPrincipal in place using Bearer claim mapping. A custom principal whose identity collection cannot safely be updated is rejected before replay consumption.
Fast.Runtime.IRefreshTokenReplayStore requires atomic consumption. Fast.Cache supplies Redis NX with expiry; the in-process fallback accepts only MemoryDistributedCache. Other distributed cache implementations need a real atomic replay store. Register a custom implementation after the default modules. Keys contain token digests, not raw credentials. Default reuse leeway is zero; a positive explicit clockSkew permits a compatibility reuse window and is not strict one-use behavior.
RequireRefreshTokenCache defaults to true, denying refresh when no replay store is registered. For compatibility, explicitly setting it to false permits refresh without consumption checks when no implementation is registered; that case has no replay protection. A registered implementation is still used.
