Skip to content

BFF Extensibility

Duende.BFF is designed to be extended at multiple layers. Most production applications will use the defaults, but each area has well-defined extension points for when you need to go beyond the defaults.

AreaWhat You Can CustomizeDetail Page
Management EndpointsLogin, logout, user info, back-channel logout, diagnostics, silent login processingManagement Endpoints
Session StoreWhere server-side session data is persisted (custom database, cache, etc.)Session Management
HTTP ForwarderCustom HTTP clients, request/response transformations for proxied callsHTTP Forwarder
Token ManagementToken storage backend, per-route token retrieval (delegation, impersonation)Token Management

Each BFF management endpoint has a corresponding interface that you can implement to customize its behavior. In v4, the pattern is to map a custom route at the same path and call the default endpoint implementation, allowing you to add logic before and after default processing.

EndpointDefault PathInterface (v4)Interface (v3)Detail
Login/bff/loginILoginEndpointILoginServiceLogin Extensibility
Logout/bff/logoutILogoutEndpointILogoutServiceLogout Extensibility
User/bff/userIUserEndpointIUserServiceUser Extensibility
Silent Login/bff/silent-loginISilentLoginEndpointISilentLoginServiceSilent Login Extensibility
Back-Channel Logout/bff/backchannelIBackchannelLogoutEndpointIBackchannelLogoutServiceBack-Channel Logout Extensibility
Diagnostics/bff/diagnosticsIDiagnosticsEndpointIDiagnosticsServiceDiagnostics Extensibility

All management endpoint customizations in v4 follow the same pattern:

Program.cs
var bffOptions = app.Services.GetRequiredService<IOptions<BffOptions>>().Value;
app.MapGet(bffOptions.LoginPath, async (HttpContext context, CancellationToken ct) =>
{
// Custom logic before the default processing
var endpoint = context.RequestServices.GetRequiredService<ILoginEndpoint>();
await endpoint.ProcessRequestAsync(context, ct);
// Custom logic after the default processing
});

By default, BFF uses either an in-memory store or Entity Framework Core for server-side sessions. To use a different storage backend (Redis, custom database, etc.), implement IUserSessionStore:

builder.Services.AddBff()
.AddServerSideSessions<MyCustomSessionStore>();

See Session Management Extensibility for the full interface and implementation guidance.

When using MapRemoteBffApiEndpoint, BFF uses a default HTTP client and a default set of request/response transformations. You can customize:

  • The HTTP client — implement IForwarderHttpClientFactory to use a proxy, custom certificates, etc.
  • Request/response transformations — add custom headers, modify paths, or replace the default transformer entirely.

See HTTP Forwarder Extensibility for details.

BFF’s token management (powered by Duende.AccessTokenManagement) can be extended in two ways:

  • Custom token store — implement IUserTokenStore to store tokens outside of the session cookie or server-side session.
  • Per-route token retrieval — implement IAccessTokenRetriever for scenarios like token exchange or impersonation, where different API routes need different tokens.
app.MapRemoteBffApiEndpoint("/api/delegated", new Uri("https://api.example.com"))
.WithAccessToken(RequiredTokenType.User)
.WithAccessTokenRetriever<DelegationTokenRetriever>();

See Token Management Extensibility for details.