Skip to content

Commit 97255a7

Browse files
committed
Merge branch 'main' into ar/more-specific-isolation
2 parents 8bae10c + 6123fe5 commit 97255a7

47 files changed

Lines changed: 3245 additions & 1564 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

astro/astro.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export default defineConfig({
8080
label: "IdentityModel",
8181
description:
8282
"Documentation for Duende's open-source IdentityModel library which provides an object model to interact with the endpoints defined in the various OAuth and OpenId Connect specifications",
83-
paths: ["accesstokenmanagement/**"],
83+
paths: ["identitymodel/**"],
8484
},
8585
{
8686
label: "IdentityModel.OidcClient",

astro/src/content/docs/bff/architecture/index.md

Lines changed: 0 additions & 100 deletions
This file was deleted.
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
---
2+
title: "Architecture"
3+
description: Overview of BFF host architecture, including authentication, session management, and integration with ASP.NET Core components
4+
date: 2020-09-10T08:22:12+02:00
5+
sidebar:
6+
order: 1
7+
label: "Overview"
8+
redirect_from:
9+
- /bff/v2/architecture/
10+
- /bff/v3/architecture/
11+
- /identityserver/v5/bff/architecture/
12+
- /identityserver/v6/bff/architecture/
13+
- /identityserver/v7/bff/architecture/
14+
---
15+
16+
import { CardGrid, LinkCard } from "@astrojs/starlight/components";
17+
18+
A BFF host is an ASP.NET Core application that acts as a security proxy between the browser and your backend APIs. Understanding the key architectural decisions up front will save you significant rework later.
19+
20+
:::tip[New to BFF?]
21+
If you haven't yet decided whether to use BFF, start with the [overview](/bff/) which covers the threat model and the BFF-vs-token-in-browser comparison.
22+
:::
23+
24+
## How the BFF Fits Into Your System
25+
26+
The following diagram shows how the BFF protects browser-based applications:
27+
28+
```mermaid
29+
flowchart TD
30+
subgraph Browser
31+
SPA["Browser-Based Application"]
32+
CookieJar["🍪 Cookie Jar"]
33+
end
34+
35+
subgraph BFF["BFF Host"]
36+
AuthEndpoints["Authentication<br/>Endpoints"]
37+
SessionMgmt["Session<br/>Management"]
38+
CookieAuth["Cookie Authorization"]
39+
CSRF["CSRF Protection"]
40+
Proxy["Proxy to<br/>External APIs"]
41+
LocalAPIs["Local APIs"]
42+
SessionStore[("Server-Side<br/>Session Storage")]
43+
end
44+
45+
IdP["Identity Provider"]
46+
ExternalAPIs["External APIs"]
47+
48+
SPA -->|"login / logout"| AuthEndpoints
49+
AuthEndpoints -->|"Set-Cookie"| CookieJar
50+
CookieJar -->|"Auth cookie"| CookieAuth
51+
AuthEndpoints <-->|"redirect"| IdP
52+
AuthEndpoints --> SessionMgmt
53+
SessionMgmt --> SessionStore
54+
CookieAuth --> CSRF
55+
CSRF --> Proxy
56+
CSRF --> LocalAPIs
57+
Proxy -->|"Bearer token"| ExternalAPIs
58+
SessionMgmt -->|"Acquire tokens"| IdP
59+
ExternalAPIs -->|"Validate tokens"| IdP
60+
```
61+
62+
The BFF sits between the browser and everything else. The browser only ever holds a **session cookie** — it never sees tokens. The BFF exchanges that cookie for bearer tokens when forwarding requests to downstream APIs.
63+
64+
## Architectural Decisions
65+
66+
### Decision 1: Where Does Your UI Live?
67+
68+
The simplest setup hosts both the UI assets and the BFF from the **same origin**. This makes cookies same-site, eliminates CORS, and avoids [third-party cookie blocking](/bff/architecture/third-party-cookies.md).
69+
70+
You can also run the frontend on a **separate origin** (e.g. a Vite dev server, a CDN) and point it at the BFF via CORS. This is more complex but enables independent deployment.
71+
72+
<LinkCard
73+
href="/bff/architecture/ui-hosting/"
74+
title="UI Hosting"
75+
description="Full comparison of same-origin vs. separate-origin hosting"
76+
/>
77+
78+
### Decision 2: Cookie-Only vs. Server-Side Sessions
79+
80+
By default, the BFF stores the entire session in the cookie. This is simple and stateless but has limits: cookie size, no server-side revocation.
81+
82+
With **server-side sessions**, the cookie holds only a session ID. The server stores the session state (typically in a database or distributed cache). This enables:
83+
- Forced logout across all sessions
84+
- Back-channel logout from the identity provider
85+
- Querying active sessions
86+
87+
<LinkCard
88+
href="/bff/fundamentals/session/server-side-sessions/"
89+
title="Server-Side Sessions"
90+
description="Configure server-side session storage for scalability and revocation"
91+
/>
92+
93+
### Decision 3: How Do You Expose APIs?
94+
95+
| API Pattern | When to Use |
96+
|---|---|
97+
| **Local API** | Business logic hosted inside the BFF process itself. Lowest latency, no token forwarding needed. |
98+
| **Remote API (direct)** | External microservice. BFF forwards the request with a bearer token attached. |
99+
| **Remote API (YARP)** | External microservice with complex routing rules. BFF uses YARP as the reverse proxy. |
100+
101+
<LinkCard
102+
href="/bff/fundamentals/apis/"
103+
title="API Types"
104+
description="Decision flowchart for choosing the right API pattern"
105+
/>
106+
107+
### Decision 4: Single Frontend vs. Multi-Frontend
108+
109+
Each BFF instance is tied to **one** browser-based application and **one** OIDC client registration. If you have multiple frontends (e.g. a customer portal and an admin app), run separate BFF instances with separate client IDs. They can share infrastructure (same process, different routes) but should not share session state or token storage.
110+
111+
<LinkCard
112+
href="/bff/fundamentals/options/#common-configurations"
113+
title="Common Configurations"
114+
description="Multi-frontend configuration example"
115+
/>
116+
117+
### Decision 5: Blazor or JavaScript?
118+
119+
Both are supported, but have different integration patterns:
120+
121+
- **JavaScript SPAs** interact with the BFF via `/bff/user`, `/bff/login`, `/bff/logout`, and API endpoints
122+
- **Blazor** uses built-in `AuthenticationStateProvider` integration and can call APIs server-side (no token forwarding from browser)
123+
124+
<LinkCard
125+
href="/bff/fundamentals/blazor/"
126+
title="Blazor Fundamentals"
127+
description="Blazor-specific guidance for rendering modes, data access, and auth state"
128+
/>
129+
130+
## Trust Boundaries
131+
132+
```mermaid
133+
flowchart TD
134+
subgraph Browser["Browser (untrusted)"]
135+
B1["Holds session cookie only<br/>(HttpOnly, Secure, SameSite)"]
136+
B2["Never sees access or refresh tokens"]
137+
end
138+
139+
subgraph BFF["BFF Host (trusted server)"]
140+
BFF1["Validates session cookie on every request"]
141+
BFF2["Manages access/refresh tokens in server memory or DB"]
142+
BFF3["Enforces anti-forgery (X-CSRF header) on API routes"]
143+
end
144+
145+
subgraph IdP["Identity Provider<br/>(e.g. IdentityServer)"]
146+
end
147+
148+
subgraph APIs["Downstream APIs<br/>(microservices, external)"]
149+
end
150+
151+
Browser -->|"HTTPS + Cookie"| BFF
152+
BFF -->|"OIDC/OAuth (HTTPS)"| IdP
153+
BFF -->|"Bearer token (HTTPS)"| APIs
154+
```
155+
156+
The critical security property: **tokens never cross the trust boundary into the browser**. All token operations happen server-to-server.
157+
158+
## Internals
159+
160+
Duende.BFF is built on top of:
161+
162+
| Component | Role | Details |
163+
|---|---|---|
164+
| ASP.NET OIDC handler | Protocol processing (auth code + PKCE, token exchange) | Standard ASP.NET middleware |
165+
| ASP.NET Cookie handler | Session management and cookie issuance | Extended by BFF for server-side sessions |
166+
| Duende.AccessTokenManagement | Token storage, refresh, revocation | [Docs](/accesstokenmanagement/index.mdx) |
167+
| YARP | Reverse proxy for remote APIs | [BFF YARP integration](/bff/fundamentals/apis/yarp.md) |
168+
169+
## See Also
170+
171+
<CardGrid>
172+
<LinkCard
173+
href="/identityserver/fundamentals/clients/"
174+
title="IdentityServer Client Configuration"
175+
description="Register your BFF as a confidential OIDC client"
176+
/>
177+
<LinkCard
178+
href="/bff/architecture/third-party-cookies/"
179+
title="Third-Party Cookies"
180+
description="How browser cookie restrictions affect BFF architecture"
181+
/>
182+
<LinkCard
183+
href="/bff/architecture/ui-hosting/"
184+
title="UI Hosting"
185+
description="Options for hosting the frontend alongside the BFF"
186+
/>
187+
<LinkCard
188+
href="/bff/fundamentals/middleware-pipeline/"
189+
title="Middleware Pipeline"
190+
description="Canonical middleware order reference"
191+
/>
192+
</CardGrid>
193+

astro/src/content/docs/bff/architecture/multi-frontend.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,17 @@ BFF V4 still allows you to manually configure the ASP.NET Core authentication op
7272

7373
To achieve this, the BFF automatically configures the ASP.NET Core pipeline:
7474

75-
![BFF Multi-Frontend Pipeline](../images/bff_multi_frontend_pipeline.svg)
75+
```mermaid
76+
---
77+
title: BFF Middleware Pipeline
78+
---
79+
flowchart TD
80+
A["FrontendSelectionMiddleware"] --> B["PathMappingMiddleware"]
81+
B --> C["OpenIdCallbackMiddleware"]
82+
C --> D["Your ASP.NET Core Pipeline"]:::app
83+
D --> E["MapRemoteRoutesMiddleware"]
84+
E --> F["ProxyIndexMiddleware"]
85+
```
7686

7787
1. `FrontendSelectionMiddleware` - This middleware performs the frontend selection by seeing which frontend's selection criteria best matches the incoming request route. It's possible to mix both path based routing and host based routing, so the most specific will be selected.
7888
2. `PathMappingMiddleware` - If you use path mapping, in the selected frontend, then it will automatically map the frontend's path so none of the subsequent middlewares know (or need to care) about this fact.

0 commit comments

Comments
 (0)