Session Management Endpoints

Duende.BFF adds endpoints for managing typical session-related operations like triggering login and logout and getting information about the currently logged-on user. These endpoint are meant to be called by the frontend.

In addition we add an implementation of the OpenID Connect back-channel notification endpoint to overcome the restrictions of third party cookies in front-channel notification in modern browsers.

You enable the endpoints by adding the relevant services into the DI container:

public void ConfigureServices(IServiceCollection services)
{
    // Add BFF services to DI - also add server-side session management
    services.AddBff(options => 
    {
        // default value
        options.ManagementBasePath = "/bff";
    };

    // rest omitted
}

Endpoint routing is used to map the management endpoints:

public void Configure(IApplicationBuilder app)
{
    // rest omitted

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBffManagementEndpoints();
    });

MapBffManagementEndpoints adds all BFF management endpoints. You can also map every endpoint individually by calling the various MapBffManagementXxxEndpoint APIs, for example endpoints.MapBffManagementLoginEndpoint().

The following describes the default behavior of those endpoints. See the extensibility section for more information how to provide custom implementations.

Login

The login endpoint triggers authentication with the scheme configured for challenge (typically the OpenID Connect handler).

GET /bff/login

By default the login endpoint will redirect back to the root of the application after authentication is done. Alternatively you can use a different local URL instead:

GET /bff/login?returnUrl=/page2

User

The user endpoint returns data about the currently logged-on user and the session.

To protect against cross-site request forgery, you need to add a static header to the GET request. Both header name and value can be configured on the options.

GET bff/user

x-csrf: 1

If there is no current session, the user endpoint will return a 401 status code. This endpoint can also be used to periodically query if the session is still valid.

If your backend uses sliding cookies, you typically want to avoid that querying the session will extend the session lifetime. Adding the slide=false query string parameter to the URL will prohibit that.

This features requires either usage of server-side sessions, or .NET 6 or higher (or both).

GET bff/user?slide=false

x-csrf: 1

If there is a valid session, the user endpoint returns a JSON array containing the contents of the ASP.NET Core authentication session and BFF specific management data, e.g.:

[
  {
    "type": "sid",
    "value": "173E788068FFB728806501F4F46C52D6"
  },
  {
    "type": "sub",
    "value": "88421113"
  },
  {
    "type": "idp",
    "value": "local"
  },
  {
    "type": "name",
    "value": "Bob Smith"
  },
  {
    "type": "bff:logout_url",
    "value": "/bff/logout?sid=173E788068FFB728806501F4F46C52D6"
  },
  {
    "type": "bff:session_expires_in",
    "value": 28799
  },
  {
    "type": "bff:session_state",
    "value": "q-Hl1V9a7FCZE5o-vH9qpmyVKOaeVfMQBUJLrq-lDJU.013E58C33C7409C6011011B8291EF78A"
  }
]

You can customize the contents of the ASP.NET Core session via the OpenID Connect handler’s ClaimAction infrastructure, or using claim transformation.

Duende.BFF adds three additional elements to the list:

bff:session_expires_in

This is the number of seconds the current session will be valid for

bff:session_state

This is the session state value of the upstream OIDC provider that can be use for the JavaScript check_session mechanism (if provided).

bff:logout_url

This is the URL to trigger logout. If the upstream provider includes an sid claim, the BFF logout endpoint requires this value as a query string parameter for CSRF protection. This behavior can be configured on the options.

Silent Login

The silent login endpoint is designed to trigger authentication much in the same way the login endpoint would, but in a non-interactive way.

The expected usage pattern would be that the application code loads in the browser and first triggers a request to the User Endpoint, and if that indicates that there is no session in the BFF backend, then the Silent Login Endpoint can be requested to automatically log the user in (assuming there is an existing session at the OIDC provider).

This non-interactive design relies upon the use of an iframe to make the silent login request. The result of the silent login request in the iframe will then use postMessage to notify the parent window of the outcome. If the result is that a session has been established, then the application logic can either re-trigger a call to the User Endpoint, or simply reload the entire page (depending on the preferred design).

To trigger the silent login, the applicaiton code must have an iframe and then set its src to the silent login endpoint. For example in your HTML:

<iframe id="bff-silent-login"></iframe>

And then in JavaScript:

document.querySelector('#bff-silent-login').src = '/bff/silent-login';

To then receive the result, the application would handle the message event in the browser and look for the data.isLoggedIn property on the event object:

window.addEventListener("message", e => {
  if (e.data && e.data.source === 'bff-silent-login' && e.data.isLoggedIn) {
      // we now have a user logged in silently, so reload this window
      window.location.reload();
  }
});

The silent login endpoint was added in version 1.2.0.

Logout

This endpoint triggers local and upstream logout. If the upstream IdP sent a session ID, this must be appended to the URL:

GET /bff/logout?sid=xyz

By default the logout endpoint will redirect back to the root of the application after logout is done. Alternatively you can use a local URL instead:

GET /bff/logout?sid=xyz&returnUrl=/loggedout

The logout endpoint will trigger revocation of the user’s refresh token (if present). This can be configured on the options.

Diagnostics

The diagnostics endpoint returns the current user and client access token for testing purposes.

GET /bff/diagnostics

This endpoint is only enabled in Development mode.

Back-channel logout notifications

The /bff/backchannel endpoint is an implementation of the OpenID Connect Back-Channel Logout specification.

The endpoint will call the registered session revocation service to revoke the user session when it receives a valid logout token. You need to enable server-side session for this feature to work.

By default, only the specific session of the user will be revoked. Alternatively, you can configure the endpoint to revoke every session that belongs to the given subject ID.