Developer Tools / Methrax.Bff.AspNetCore / Architecture
Architecture
Methrax.Bff.AspNetCore places an ASP.NET Core Backend-for-Frontend between the browser and identity/downstream services. The browser owns only a secure session cookie; OAuth/OIDC tokens remain on the server when token persistence is enabled.
System architecture
flowchart TB
SPA[Angular / Browser SPA]
BFF[ASP.NET Core BFF\nMethrax.Bff.AspNetCore]
SESSION[(Server-side ITicketStore\nMemory / Redis / DB)]
IDP[OpenID Connect Provider\ne.g. Keycloak]
PROXY[YARP / BFF API endpoints]
HTTP[HttpClient + TokenForwardingHandler]
API1[Downstream Service]
API2[Downstream Microservice]
SPA -->|Secure HttpOnly\nSameSite cookie| BFF
BFF <-->|Authentication ticket| SESSION
BFF <-->|Authorization Code + PKCE| IDP
BFF --> PROXY
BFF --> HTTP
PROXY -->|Bearer access token| API1
HTTP -->|Bearer access token| API2
Authentication flow
sequenceDiagram
autonumber
actor User
participant Browser as Browser / SPA
participant BFF as ASP.NET Core BFF
participant IdP as OIDC Provider
participant Store as ITicketStore
participant API as Downstream API
User->>Browser: Open protected application
Browser->>BFF: GET /login
BFF-->>Browser: OIDC challenge redirect
Browser->>IdP: Authorization request + PKCE
IdP-->>Browser: Authorization code
Browser->>BFF: OIDC callback
BFF->>IdP: Exchange code for tokens
IdP-->>BFF: ID / access / refresh tokens
BFF->>Store: Persist ticket + tokens (optional)
BFF-->>Browser: Secure HttpOnly session cookie
Browser->>BFF: Authenticated request + cookie
BFF->>API: Bearer token delegation (when enabled)
API-->>BFF: API response
BFF-->>Browser: Application response
Browser security boundary
The intended boundary is zero-token browser handling. Application JavaScript should not read, persist or forward raw access/refresh tokens. The browser uses the session cookie and the BFF owns OIDC and downstream token concerns.
Session strategy
When EnableServerSideSessions is enabled, an ITicketStore keeps authentication tickets away from the browser. This reduces cookie size and provides a path to distributed stores for multi-instance deployments.
flowchart LR
C[Browser Cookie\nSession key only] --> B[BFF]
B --> S{ITicketStore}
S --> M[MemoryCache\nlocal/dev]
S --> R[Redis / distributed cache\nscale-out]
S --> D[Database-backed store\ncustom provider]
Token persistence decision
flowchart TD
Q{Does the BFF call APIs\non behalf of the user?}
Q -->|Yes| A[SaveTokens = true]
A --> B[Prefer server-side sessions]
B --> C[Use YARP transforms or\nTokenForwardingHandler]
Q -->|No| D[SaveTokens = false]
D --> E[Claims/session-only BFF]