Multi-Strategy Auth for ASP.NET SDK
π£ Wristband ASP.NET Auth SDK 4.0.0 Release π
Release 4.0.0
Breaking Changes
Migration Guide: https://github.com/wristband-dev/aspnet-auth/blob/main/migration/v4/README.md
π .NET Version Requirements
.NET 6 and .NET 7 are no longer supported. This SDK now requires .NET 8 or later.
π Query Parameter and URL Placeholder Standardization
Query Parameters:
tenant_domainβtenant_name
URL Placeholders:
{tenant_domain}β{tenant_name}({tenant_domain}is deprecated but still supported for backward compatibility)
Config and Model Fields:
LoginConfig.DefaultTenantDomainNameβLoginConfig.DefaultTenantNameLogoutConfig.TenantDomainNameβLogoutConfig.TenantNameCallbackData.TenantDomainNameβCallbackData.TenantName
π CallbackResult Changes
The CallbackResultType enum values have changed from screaming snake case to PascalCase.
Migration:
CallbackResultType.REDIRECT_REQUIREDβCallbackResultType.RedirectRequiredCallbackResultType.COMPLETEDβCallbackResultType.Completed- New
Reasonfield onCallbackResultindicates why a redirect was required (see Callback Failure Reasons )
ποΈ Session Management Overhaul
Manual SignInAsync/SignOutAsync session management has been replaced with SDK-provided extension methods and middleware.
Migration:
- Replace manual claims construction +
SignInAsyncwithhttpContext.CreateSessionFromCallback() - Replace
SignOutAsyncwithhttpContext.DestroySession() - Replace
context.User.FindFirst("...")with typed getters:GetUserId(),GetRefreshToken(),GetTenantName(), etc. - Delete your custom
AuthMiddlewareclass entirely β token refresh and session validation are now handled by the built-in authorization handler - Replace
.WithMetadata(new RequireWristbandAuth())with.RequireWristbandSession() - Add
app.UseWristbandSessionMiddleware()afterUseAuthorization()inProgram.cs
π§ Cookie Configuration Changes
Manual cookie configuration has been replaced with a single method call.
Migration:
- Replace all manual cookie options +
UseWristbandApiStatusCodes()withoptions.UseWristbandSessionConfig() UseWristbandApiStatusCodes()no longer exists β its behavior is included inUseWristbandSessionConfig()- Default
SameSitepolicy changed fromStricttoLax. Override afterUseWristbandSessionConfig()if your app requiresStrict
π‘οΈ Authorization Setup Changes
Two new service registrations are now required before Build(), and middleware order has changed.
Migration:
- Add
builder.Services.AddWristbandAuthorizationHandler() - Add
builder.Services.AddAuthorization(options => options.AddWristbandDefaultPolicies()) - Add
app.UseAuthorization()afterUseAuthentication()and beforeUseWristbandSessionMiddleware() - Remove
app.UseMiddleware<AuthMiddleware>()
π Session Endpoint Changes
Manual session response construction has been replaced with an SDK method.
Migration:
- Replace manual
Results.Ok(new { userId = ..., tenantId = ..., metadata = ... })withhttpContext.GetSessionResponse(metadata: ...) GetSessionResponse()automatically setsCache-Control: no-storeandPragma: no-cacheheaders β no need to set them manually
π¦ Typed UserInfo
CallbackData.Userinfo is no longer a raw JSON dictionary. It is now a typed UserInfo object.
Migration:
- Replace
userinfo.TryGetValue("sub", ...)withuserinfo.UserId - Replace
userinfo.TryGetValue("tnt_id", ...)withuserinfo.TenantId - Replace
userinfo.TryGetValue("email", ...)withuserinfo.Email - See the [Callback() documentation](https://github.com/wristband-dev/aspnet-auth/blob/main/README.md#callback) for the full list of typed fields
New Features
π JWT Bearer Token Authentication
New RequireWristbandJwt() policy supports stateless JWT bearer token authentication powered by [@wristband/aspnet-jwt](https://github.com/wristband-dev/aspnet-jwt).
Features:
- JWT signature verification via JWKS with automatic key caching and rotation
- Configurable JWK cache size and TTL
- Validated JWT payload available via
GetJwt()andGetJwtPayload() - Full type safety with
JWTPayloadmodel including standard and custom Wristband claims
β¨ Multi-Strategy Authentication
New AddWristbandMultiStrategyPolicy() and RequireWristbandMultiAuth() support multiple authentication strategies with fallback behavior on a single endpoint.
Supported Strategies:
SESSIONβ Cookie-based session authentication with automatic token refreshJWTβ Bearer token authentication with JWKS validation
Features:
- Strategies are tried in the order you specify until one succeeds
- Automatic access token refresh for expired tokens (SESSION strategy)
- Optional CSRF token validation (SESSION strategy)
- Support for custom policy names when multiple multi-strategy policies are needed
π‘οΈ CSRF Protection
New opt-in CSRF protection via AddWristbandCsrfProtection() using a dual-cookie synchronizer token pattern.
Features:
- Cryptographically secure token generated on session creation
- Token stored in both the encrypted session cookie and a JavaScript-readable CSRF cookie
- Automatic validation on all requests to
RequireWristbandSession()endpoints - Configurable header name, cookie name, and cookie domain
π Callback Failure Reasons
CallbackResult now includes a Reason field when Type is RedirectRequired, indicating why the redirect was required:
MissingLoginStateβ Login state cookie was not foundInvalidLoginStateβ Login state validation failedLoginRequiredβ Wristband returned alogin_requirederrorInvalidGrantβ Authorization code was invalid or expired
Recommended Updates
π Token Endpoint
New GetTokenResponse() method provides a standard pattern for endpoints that expose the access token to your frontend for direct API calls.
app.MapGet("/auth/token", (HttpContext httpContext) =>
{
var response = httpContext.GetTokenResponse();
return Results.Ok(response);
})
.RequireWristbandSession();GetTokenResponse() automatically sets Cache-Control: no-store and Pragma: no-cache headers.
For full documentation, see the [README](https://github.com/wristband-dev/aspnet-auth/blob/main/README.md).