Identity Broker Overview
The Identity Broker is a server-side authentication middleware for ASP.NET Core that manages the complete login lifecycle — local credentials, OIDC/SAML SSO, MFA, and session management — on your behalf. It keeps all tokens on the server and issues a single encrypted, HttpOnly cookie to the browser, implementing the Backend-for-Frontend (BFF) security pattern recommended by OWASP.
Why Identity Broker?
Modern security standards (OWASP 2026) discourage storing access tokens in the browser (LocalStorage/SessionStorage) due to XSS risks. The Identity Broker handles all token exchanges on the server and issues a secure, encrypted, partitioned cookie to the frontend.
| Feature | Client-Side Auth (Standard) | Identity Broker (BFF) |
|---|---|---|
| Token Storage | LocalStorage (Vulnerable to XSS) | HttpOnly Cookie (Secure) |
| Encryption | None (JWT visible) | AES-256 Encrypted Cookie |
| CSRF | Rely on Samesite | Double-Submit Cookie Pattern |
| Privacy | 3rd Party Cookies (Blocked by Safari) | First-Party Context |
Decision guide
- Identity Validator: Use this if your APIs already receive JWTs and only need token validation.
- Identity Broker: Use this if you need a complete login experience for a browser app and want secure cookie sessions.
- Both: Use Broker for the SPA and Validator for downstream APIs.
See: Identity Validator Overview
Supported Providers
The broker supports seamless integration with major enterprise identity providers.
Azure AD / Entra ID
Multi-tenant SaaS support with Admin Consent flow.
Auth0
B2B SaaS isolation with Organizations.
Business login with Hosted Domain restrictions.
Okta
Workforce identity with PKCE and Authorization Code flow.
Custom / Generic SAML
ADFS, Shibboleth, PingFederate, or any SAML 2.0 IdP without a dedicated provider page.
Key Capabilities
Zero-Knowledge Frontend
The frontend application never sees the Access Token. It only holds a session cookie. This renders XSS attacks ineffective for token theft.
Just-In-Time (JIT) Provisioning
Automatically provision users in your local database when they log in via a trusted provider (like a corporate Azure AD).
Advanced Security
- AES-256 Encryption: Session cookies are encrypted using ASP.NET Data Protection, which uses AES-256-CBC by default. Even if an attacker intercepts the cookie, the token payload inside is unreadable without the server’s Data Protection keys.
- Partitioned Cookies (CHIPS): Browsers are restricting third-party cookies. The broker activates the
Partitionedcookie attribute automatically when your app usesSameSite=Nonewith HTTPS, ensuring the cookie remains usable in cross-site embedding scenarios. Most apps use the defaultSameSite=Strictand are unaffected. - Strict CSRF: Uses the Double-Submit Cookie pattern. The server sets an
XSRF-TOKENcookie that JavaScript can read. Every POST must echo that value in anX-Primus-CSRFheader. A third-party site cannot read your cookie, so it cannot forge a valid request.
Both tabs are the same origin — browsers correctly share cookies across all tabs from the same website, and this is expected. The XSRF-TOKEN cookie is deliberately readable by your own JavaScript (it is not HttpOnly) so your frontend can echo it as a header.
The protection works at the domain level: a completely different website (for example, evil.com) cannot read your XSRF-TOKEN cookie due to the browser's Same-Origin Policy, so it cannot forge a valid X-Primus-CSRF header. Your own tabs can always see the cookie — a malicious third-party site cannot.
Next Steps
Quickstart — get running in 15 minutes →- Tenant-Routed Login — separate tenant IdPs and platform-admin IdPs by host and tenant metadata
- Provider Setup — where each provider credential and metadata value comes from
- Database Setup — persist users with EF Core (SQLite, PostgreSQL, SQL Server)
- Advanced Configuration — custom stores, HA clustering
- Edge Cases — callback, MFA, and SSO troubleshooting
- Endpoint Reference — every
/api/auth/*endpoint
Technical Specifications
| Feature | Default Value | Description |
|---|---|---|
| Session Lifetime | 60 minutes sliding | Session resets on every active request (SlidingExpiration = true). Configure via Jwt:ExpiryInMinutes in appsettings (default: 60). |
| Cookie Name | Primus.Session | Prefixed with __Host- in non-development environments for maximum browser security. |
| Session cookie mode | Cookie (HttpOnly) | Default. Browser never sees the token. Switch to JWT mode by setting IssueLocalJwt: true — used only when your stack needs a Bearer token instead of a cookie. |
| CSRF Cookie | XSRF-TOKEN | Readable by JavaScript (intentional). Set automatically on the first request through the broker middleware. Calling GET /api/auth/providers is the recommended first step. |
| CSRF Header | X-Primus-CSRF | Required on all POST requests to /api/auth/*. Your frontend reads XSRF-TOKEN and sends its value in this header. |
| Login rate limit | 5 attempts/min per IP | Applies when BotProtection.Enabled = true. Returns 429 Too Many Requests with a Retry-After header. Not enabled by default. |
| Token Encryption | ASP.NET Data Protection | Any upstream token stored in the session cookie is encrypted using ASP.NET Data Protection (AES-256-CBC). For multi-node deployments, share keys using AddPrimusBrokerDataProtection(). |
| Upstream Token Refresh | Not yet supported | Upstream access tokens (Azure AD, Auth0, etc.) are not automatically refreshed. When they expire, downstream API calls forwarding the token receive 401. Use the provider’s own SDK (e.g. MSAL) for long-lived API access. |
| Partitioned Cookies (CHIPS) | Off by default | Activated automatically when SameSite=None and HTTPS are both enforced. Most apps use the default SameSite=Strict and are unaffected. |