Skip to content
Trouble with OAuth 2.0 in the browser? Watch Web Security and BFF with Philippe De Ryck.

Getting Started - Single Frontend

Duende.BFF (Backend for Frontend) is a library that helps you build secure, modern web applications by acting as a security gateway between your frontend and backend APIs. This guide will walk you through setting up a simple BFF application with a single frontend.

  • .NET 8.0 or later
  • A frontend application (e.g., React, Angular, Vue, or plain JavaScript)

Create a new ASP.NET Core Web Application:

Terminal window
dotnet new web -n MyBffApp
cd MyBffApp

Install the Duende.BFF package:

Terminal window
dotnet add package Duende.BFF

Add the following to your Program.cs:

builder.Services.AddBff()
.ConfigureOpenIdConnect(options =>
{
options.Authority = "https://demo.duendesoftware.com";
options.ClientId = "interactive.confidential";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.ResponseMode = "query";
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.MapInboundClaims = false;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
// Add this scope if you want to receive refresh tokens
options.Scope.Add("offline_access");
})
.ConfigureCookies(options =>
{
// Because we use an identity server that's configured on a different site
// (duendesoftware.com vs localhost), we need to configure the SameSite property to Lax.
// Setting it to Strict would cause the authentication cookie not to be sent after logging in.
// The user would have to refresh the page to get the cookie.
// Recommendation: Set it to 'strict' if your IDP is on the same site as your BFF.
options.Cookie.SameSite = SameSiteMode.Lax;
});
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseAuthentication();
app.UseRouting();
// adds antiforgery protection for local APIs
app.UseBff();
// adds authorization for local and remote API endpoints
app.UseAuthorization();
app.Run();

Make sure to replace the Authority, ClientID and ClientSecret with values from your identity provider. Also consider if the scopes are correct.

If your browser-based application uses local APIs, you can add those directly to your BFF app. The BFF supports both controllers and minimal APIs to create local API endpoints.

It’s important to mark up the APIs with .AsBffApiEndpoint(), because this adds CSRF protection.

// Aadds authorization for local and remote API endpoints
app.UseAuthorization();

// Place your custom routes after the 'UseAuthorization()'
app.MapGet("/hello-world", () => "hello-world")
  .AsBffApiEndpoint(); // Aadds CSRF protection to the controller endpoints

If you also want to call remote api’s from your browser based application, then you should proxy the calls through the BFF.

The BFF extends the capabilities of Yarp in order to achieve this.

Terminal
dotnet add package Duende.BFF.Yarp
builder.Services.AddBff()
  .AddRemoteApis(); // Adds the capabilities needed to perform proxying to remote APIs.

// ...

// Map any call (including child routes) from /api/remote to https://remote-api-address
app.MapRemoteBffApiEndpoint("/api/remote", new Uri("https://remote-api-address"))
  .WithAccessToken(RequiredTokenType.Client);

By default, Duende.BFF uses an in-memory session store. This is suitable for development and testing, but not recommended for production as sessions will be lost when the application restarts.

builder.Services.AddBff()
  .AddServerSideSessions(); // Uses in-memory session store by default

// ...existing code for authentication, authorization, etc.