Loading...
} else { @foreach (var item in items) {@item.Value
} } @code { private Data[]? items; protected override async Task OnInitializedAsync() { items = await DataAccessor.GetData(); } } ``` ## See Also [Section titled “See Also”](#see-also) [Embedded (Local) APIs ](/bff/fundamentals/apis/local/)Full reference for BFF-hosted endpoints [Proxying Remote APIs ](/bff/fundamentals/apis/remote/)Direct forwarding to upstream services [YARP Integration ](/bff/fundamentals/apis/yarp/)Advanced reverse proxy configuration [Rendering Modes & BFF ](/bff/fundamentals/blazor/rendering-modes/)Which Blazor modes need BFF [Getting Started: Blazor ](/bff/getting-started/blazor/)Full setup walkthrough ----- # Blazor Rendering Modes & BFF > Learn which Blazor rendering modes are compatible with the BFF security pattern and why. Blazor supports [several rendering modes](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0#render-modes). The BFF pattern is only applicable to modes where code runs in the browser (client context), because that is where the risk of token exposure exists. ## Rendering Mode Compatibility [Section titled “Rendering Mode Compatibility”](#rendering-mode-compatibility) | Mode | Description | Renders In | Interactive | Use BFF? | | --------------------------- | ------------------------------------------------------------- | ---------------- | ----------- | -------- | | **Static Server** | Static server-side rendering (SSR) | Server | ❌ | ❌ | | **Interactive Server** | Interactive SSR using Blazor Server and WebSockets | Server | ✅ | ❌ | | **Interactive WebAssembly** | Client-side rendering (CSR) using Blazor WASM | Browser | ✅ | ✅ | | **Interactive Auto** | Starts as Interactive Server, switches to WASM after download | Server → Browser | ✅ | ✅ | ## Static Server [Section titled “Static Server”](#static-server) Caution BFF is not necessary for Static Server rendering. Standard ASP.NET Core authentication patterns apply. Static Server renders Blazor components as plain HTML with no client-side interactivity. Because all rendering happens on the server, tokens never reach the browser. Use standard ASP.NET Core cookie authentication instead of BFF. You may still want to use the `AuthenticationStateProvider` for accessing user claims in components. ## Interactive Server [Section titled “Interactive Server”](#interactive-server) Caution BFF is not typically necessary for Interactive Server rendering. All component interactivity is managed server-side via WebSockets (SignalR). In Interactive Server mode, Blazor components run on the server and push UI updates to the browser over a WebSocket connection. Because no application code runs in the browser, tokens remain server-side naturally. You can still use [Session Management](/bff/fundamentals/session/) features of BFF if you want server-side session control, but the BFF security pattern itself is not required. ## Interactive WebAssembly [Section titled “Interactive WebAssembly”](#interactive-webassembly) In Interactive WebAssembly mode, the Blazor runtime and your application code are downloaded to and executed in the browser. This means: * Your components run in the same JavaScript sandbox as the rest of the page * Any access token stored in the WASM memory is potentially accessible to injected scripts * You must never expose access tokens to WASM components The BFF pattern solves this by keeping tokens on the server. WASM components call BFF-hosted API endpoints (using the authentication cookie), and the BFF attaches the access token server-side before forwarding to remote APIs. See the [Getting Started: Blazor guide](/bff/getting-started/blazor/) for setup instructions. ## Interactive Auto [Section titled “Interactive Auto”](#interactive-auto) Interactive Auto combines Interactive Server and Interactive WebAssembly: rendering starts on the server but switches to client-side WASM on subsequent visits after the Blazor bundle is downloaded. Because your application may be running in the browser at any time, you cannot rely on server-side-only token handling. The BFF pattern ensures tokens remain server-side regardless of which rendering mode is active. ## Authentication State [Section titled “Authentication State”](#authentication-state) The `AuthenticationState` contains information about the currently logged-in user, including management claims like the logout URL. Blazor uses `AuthenticationStateProvider` implementations to make authentication state available to components: * **On the server**: The BFF’s `AddServerManagementClaimsTransform` enriches the claims with the logout URL. * **On the client (WASM)**: The `BffClientAuthenticationStateProvider` polls `/bff/user` to keep the client in sync with the server session. This also notifies the frontend if the session is terminated server-side (e.g., back-channel logout). ## Server-Side Token Store [Section titled “Server-Side Token Store”](#server-side-token-store) Blazor Server applications stream content over a WebSocket, so there is often no `HttpContext` available during component execution. This means: * You cannot use `HttpContext` extension methods in Blazor Server components * The normal mechanism to attach tokens to `HttpClient` calls does not work without special setup When you register `AddBlazorServer()`, BFF automatically registers the `ServerSideTokenStore` and Duende.AccessTokenManagement integration so that token management works correctly in Blazor Server. For more details, see [Blazor Server token management](/accesstokenmanagement/blazor-server/). ## See Also [Section titled “See Also”](#see-also) [Data Access Patterns ](/bff/fundamentals/blazor/data-access/)How to call APIs from Blazor components [Getting Started: Blazor ](/bff/getting-started/blazor/)Full walkthrough setup guide [Troubleshooting ](/bff/troubleshooting/)Common Blazor BFF issues ----- # Production Deployment > Guide for deploying Duende BFF to production, covering load balancing, data protection, health checks, cookie domain configuration, and monitoring. This page covers the production-specific concerns you need to address before deploying a BFF host. For middleware pipeline order, see [Middleware Pipeline](/bff/fundamentals/middleware-pipeline/). ## Load Balancing and Sticky Sessions [Section titled “Load Balancing and Sticky Sessions”](#load-balancing-and-sticky-sessions) The BFF uses ASP.NET Core’s Data Protection to encrypt and sign session cookies. In a multi-instance (load-balanced) deployment, **all instances must share the same Data Protection key ring** — otherwise cookies issued by one instance cannot be decrypted by another, causing random logout on failover. ### Shared Key Storage [Section titled “Shared Key Storage”](#shared-key-storage) Configure Data Protection to store keys in a shared location accessible to all instances: ```csharp // Using Azure Blob Storage + Azure Key Vault builder.Services.AddDataProtection() .PersistKeysToAzureBlobStorage(connectionString, "data-protection", "keys.xml") .ProtectKeysWithAzureKeyVault(keyIdentifier, credential); // Using a network file share or a database builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\dp-keys")) .ProtectKeysWithCertificate(certificate); ``` Do not use in-memory keys in production The default in-memory key ring is regenerated on every restart. Any existing sessions are invalidated when the process restarts or when traffic is routed to a new instance. See also: [Data Protection](/general/data-protection/) ### Server-Side Sessions (Recommended for Multi-Instance) [Section titled “Server-Side Sessions (Recommended for Multi-Instance)”](#server-side-sessions-recommended-for-multi-instance) With cookie-only sessions, every instance must share Data Protection keys. With **server-side sessions**, the cookie only holds an opaque session ID — the session payload is stored in a shared database. This is simpler to operate because: * Key ring only needs to be consistent (not necessarily shared) — the cookie just holds an ID * Sessions can be inspected and revoked server-side * Cookie size is minimized [Server-Side Sessions ](/bff/fundamentals/session/server-side-sessions/)Setup guide for database-backed session storage ### Sticky Sessions [Section titled “Sticky Sessions”](#sticky-sessions) If you cannot use server-side sessions and cannot share a Data Protection key ring, configure your load balancer to route each user consistently to the same instance (“sticky sessions” / session affinity). This is a last resort — prefer shared key storage. ## Health Check Endpoints [Section titled “Health Check Endpoints”](#health-check-endpoints) Expose a health check endpoint so your load balancer and orchestrator (Kubernetes, etc.) can detect unhealthy instances: ```csharp builder.Services.AddHealthChecks(); // In your pipeline (after UseRouting): app.MapHealthChecks("/health"); ``` For a more complete health check that validates downstream dependencies (database, token endpoint reachability): ```csharp builder.Services.AddHealthChecks() .AddDbContextCheckYou (@context.User.Identity?.Name) are not authorized to access this resource.
}This component demonstrates showing data.
@if (forecasts == null) {Loading...
} else {| Date | Temp. (C) | Temp. (F) | Summary |
|---|---|---|---|
| @forecast.Date.ToShortDateString() | @forecast.TemperatureC | @forecast.TemperatureF | @forecast.Summary |