Composable Endpoints
Recipes
Common composition patterns for cookie SPA, Identity bearer, JWT-only, and custom paths.
Recipe matrix
| Recipe | Management group | Sign-in group | Passkeys |
|---|---|---|---|
| Cookie SPA (default facade) | /identity | cookie /identity | /account |
| Identity bearer | /identity | bearer /identity | optional |
| JWT-only | e.g. /account | JWT /auth | optional |
| Custom paths | any prefix | matching DI | any prefix |
Advanced composition
Compose modules yourself when you need bearer Identity, custom paths, or JWT-only. Map management once in production hosts.
builder.Services
.AddIdentityApiEndpoints<AppUser>(o =>
{
o.Stores.SchemaVersion = IdentitySchemaVersions.Version3;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAntiforgery();
builder.Services.AddCookieAuthEndpoints(); // rate limits + ReAuth schemes
builder.Services.AddPasskeyEndpoints();
builder.Services.AddJwtEndpoints<AppUser, AppDbContext>(o =>
{
o.Issuer = "https://example.com";
o.Audience = "https://example.com";
o.SigningOptions.SymmetricKey = builder.Configuration["Jwt:SymmetricKey"];
});
// In AppDbContext.OnModelCreating:
// builder.UseRefreshToken();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.UseAntiforgery();
// Cookie SPA
app.MapGroup("/identity").MapIdentityManagementApi<AppUser>();
app.MapGroup("/identity").MapCookieAuthEndpoints<AppUser>();
// Or Identity bearer
// app.MapGroup("/identity").MapIdentityManagementApi<AppUser>();
// app.MapGroup("/identity").MapBearerAuthEndpoints<AppUser>();
// Or JWT-only (no cookie login)
// app.MapGroup("/account").MapIdentityManagementApi<AppUser>();
// app.MapGroup("/auth").MapJwtAuthEndpoints<AppUser>();
app.MapGroup("/account").MapPasskeyEndpoints<AppUser>();
Cookie SPA
Best default for a first-party SPA on the same site (or carefully configured CORS + credentials).
- Management + cookie on
/identity - Passkeys on
/account - Client uses credentials + CSRF token
Identity bearer
Use when the SPA stores Identity bearer tokens (ASP.NET Core Identity API token format) instead of cookies.
- Map
MapBearerAuthEndpointsinstead of cookie - CSRF is skipped for bearer-authenticated unsafe methods (see Requirements)
JWT-only
Use JWT for access tokens and an HttpOnly refresh cookie.
- Management on one prefix (e.g.
/account) MapJwtAuthEndpointson/auth(or your choice)- Still call
UseRefreshToken()and migrate - Passkeys do not issue JWT — after passkey login, call
/auth/createif you need a JWT
Custom paths
Prefixes are arbitrary as long as DI and middleware match. The Demo host uses paths such as /auth/cookie, /auth/passkey, and /auth/jwt via facade options.