Added

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.DefaultTenantName
  • LogoutConfig.TenantDomainName β†’ LogoutConfig.TenantName
  • CallbackData.TenantDomainName β†’ CallbackData.TenantName

πŸ”„ CallbackResult Changes

The CallbackResultType enum values have changed from screaming snake case to PascalCase.

Migration:

  • CallbackResultType.REDIRECT_REQUIRED β†’ CallbackResultType.RedirectRequired
  • CallbackResultType.COMPLETED β†’ CallbackResultType.Completed
  • New Reason field on CallbackResult indicates 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 + SignInAsync with httpContext.CreateSessionFromCallback()
  • Replace SignOutAsync with httpContext.DestroySession()
  • Replace context.User.FindFirst("...") with typed getters: GetUserId(), GetRefreshToken(), GetTenantName(), etc.
  • Delete your custom AuthMiddleware class entirely β€” token refresh and session validation are now handled by the built-in authorization handler
  • Replace .WithMetadata(new RequireWristbandAuth()) with .RequireWristbandSession()
  • Add app.UseWristbandSessionMiddleware() after UseAuthorization() in Program.cs

πŸ”§ Cookie Configuration Changes

Manual cookie configuration has been replaced with a single method call.

Migration:

  • Replace all manual cookie options + UseWristbandApiStatusCodes() with options.UseWristbandSessionConfig()
  • UseWristbandApiStatusCodes() no longer exists β€” its behavior is included in UseWristbandSessionConfig()
  • Default SameSite policy changed from Strict to Lax. Override after UseWristbandSessionConfig() if your app requires Strict

πŸ›‘οΈ 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() after UseAuthentication() and before UseWristbandSessionMiddleware()
  • 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 = ... }) with httpContext.GetSessionResponse(metadata: ...)
  • GetSessionResponse() automatically sets Cache-Control: no-store and Pragma: no-cache headers β€” 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:


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() and GetJwtPayload()
  • Full type safety with JWTPayload model 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 refresh
  • JWT β€” 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 found
  • InvalidLoginState β€” Login state validation failed
  • LoginRequired β€” Wristband returned a login_required error
  • InvalidGrant β€” 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).