Skip to content

Fix capitalization, add closing braces, and some formatting #685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,68 @@ redirect_from:
- /identityserver/v7/bff/extensibility/management/back-channel-logout/
---

The back-channel logout endpoint has several extensibility points organized into two interfaces and their default implementations. The *IBackchannelLogoutService* is the top level abstraction that processes requests to the endpoint. This service can be used to add custom request processing logic or to change how it validates incoming requests. When the back-channel logout endpoint receives a valid request, it revokes sessions using the *ISessionRevocationService*.
The back-channel logout endpoint has several extensibility points organized into two interfaces and their default implementations. The *IBackChannelLogoutService* is the top level abstraction that processes requests to the endpoint. This service can be used to add custom request processing logic or to change how it validates incoming requests. When the back-channel logout endpoint receives a valid request, it revokes sessions using the *ISessionRevocationService*.

## Request Processing
You can add custom logic to the endpoint by implementing the *IBackchannelLogoutService* or by extending its default implementation (*Duende.Bff.DefaultBackchannelLogoutService*). In most cases, extending the default implementation is preferred, as it has several virtual methods that can be overridden to customize particular aspects of how the request is processed.
You can add custom logic to the endpoint by implementing the *IBackChannelLogoutService* or by extending its default implementation (*Duende.Bff.DefaultBackChannelLogoutService*). In most cases, extending the default implementation is preferred, as it has several virtual methods that can be overridden to customize particular aspects of how the request is processed.

*ProcessRequestAsync* is the top level function called in the endpoint service and can be used to add arbitrary logic to the endpoint.

```csharp
public class CustomizedBackchannelLogoutService : DefaultBackchannelLogoutService
public class CustomizedBackChannelLogoutService : DefaultBackChannelLogoutService
{
public override Task ProcessRequestAsync(HttpContext context)
{
// Custom logic here

return base.ProcessRequestAsync(context);
}
}
```

## Validation

Validation of the incoming request can be customized by overriding one of several virtual methods in the *DefaultBackchannelLogoutService*. *GetTokenValidationParameters* allows you to specify the *[TokenValidationParameters](https://learn.microsoft.com/en-us/dotnet/API/microsoft.identitymodel.tokens.tokenvalidationparameters?view=azure-dotnet)* used to validate the incoming logout token. The default implementation creates token validation parameters based on the authentication scheme's configuration. Your override could begin by calling the base method and then make changes to those parameters or completely customize how token validation parameters are created. For example:
Validation of the incoming request can be customized by overriding one of several virtual methods in the *DefaultBackChannelLogoutService*. *GetTokenValidationParameters* allows you to specify the *[TokenValidationParameters](https://learn.microsoft.com/en-us/dotnet/API/microsoft.identitymodel.tokens.tokenvalidationparameters?view=azure-dotnet)* used to validate the incoming logout token. The default implementation creates token validation parameters based on the authentication scheme's configuration. Your override could begin by calling the base method and then make changes to those parameters or completely customize how token validation parameters are created. For example:

```csharp
public class CustomizedBackchannelLogoutService : DefaultBackchannelLogoutService
public class CustomizedBackChannelLogoutService : DefaultBackChannelLogoutService
{
protected override async Task<TokenValidationParameters> GetTokenValidationParameters()
{
var tokenValidationParams = await base.GetTokenValidationParameters();
// Set custom parameters here
// For example, make clock skew more permissive than it is by default:
tokenValidationParams.ClockSkew = TimeSpan.FromMinutes(15);
protected override async Task<TokenValidationParameters> GetTokenValidationParameters()
{
var tokenValidationParams = await base.GetTokenValidationParameters();

// Set custom parameters here
// For example, make clock skew more permissive than it is by default:
tokenValidationParams.ClockSkew = TimeSpan.FromMinutes(15);

return tokenValidationParams;
}
return tokenValidationParams;
}
}
```
If you need more control over the validation of the logout token, you can override *ValidateJwt*. The default implementation of *ValidateJwt* validates the token and produces a *ClaimsIdentity* using a *[JsonWebTokenHandler](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/wiki/ValidatingTokens)* and the token validation parameters returned from *GetTokenValidationParameters*. Your override could call the base method and then manipulate this *ClaimsIdentity* or add a completely custom method for producing the *ClaimsIdentity* from the logout token.

*ValidateLogoutTokenAsync* is the coarsest-grained validation method. It is responsible for validating the incoming logout token and determining if logout should proceed, based on claims in the token. It returns a *ClaimsIdentity* if logout should proceed or null if it should not. Your override could prevent logout in certain circumstances by returning null. For example:

```csharp
public class CustomizedBackchannelLogoutService : DefaultBackchannelLogoutService
public class CustomizedBackChannelLogoutService : DefaultBackChannelLogoutService
{
protected override async Task<ClaimsIdentity?> ValidateLogoutTokenAsync(string logoutToken)
{
var identity = await base.ValidateLogoutTokenAsync(logoutToken);

// Perform custom logic here
// For example, prevent logout based on certain conditions
if(identity?.FindFirst("sub")?.Value == "12345")
{
return null;
}
else
protected override async Task<ClaimsIdentity?> ValidateLogoutTokenAsync(string logoutToken)
{
return identity;
var identity = await base.ValidateLogoutTokenAsync(logoutToken);

// Perform custom logic here
// For example, prevent logout based on certain conditions
if(identity?.FindFirst("sub")?.Value == "12345")
{
return null;
}
else
{
return identity;
}
}
}
}
```

## Session Revocation
The back-channel logout service will call the registered session revocation service to revoke the user session when it receives a valid logout token. To customize the revocation process, implement the *ISessionRevocationService*.
The back-channel logout service will call the registered session revocation service to revoke the user session when it receives a valid logout token. To customize the revocation process, implement the *ISessionRevocationService*.