Releases: DuendeSoftware/products
IdentityServer 7.2.4
This is a patch release that fixes a null reference exception that could occur if a client configuration is removed while active server side sessions exist that involve that client.
Detailed changelog
- Add null-check for client before coordinating session lifecycle by @khalidabuhakmeh in https://github.com/DuendeSoftware/products/pull/2038
Full Changelog: is-7.2.3...is-7.2.4
BFF 4.0.0-Preview1
This release is a major change from the previous release. The biggest improvement here is multi-frontend support.
The extensibility approach has been drastically changed. To reduce the public API surface, and improve our ability to evolve the library, we no longer make every class in the system public with virtual methods. Implementation logic now is internal.
Changes and improvements
- Support for login prompts, such as prompt = create => https://github.com/DuendeSoftware/products/issues/1701
- Deprecated silent login endpoint in favor of prompt=none
- Allow anti forgery check to be disabled via a delegate => https://github.com/DuendeSoftware/products/pull/1932
- Multi-frontend support => https://github.com/DuendeSoftware/products/pull/2032
- Duende.AccessTokenManagement V4 => https://github.com/DuendeSoftware/products/pull/2032
- Open Telemetry support => https://github.com/DuendeSoftware/products/pull/1945
Upgrade guide
This release introduces many breaking changes. Some small, some large. We'll do our best to document how to upgrade here. Should you run into an upgrade issue that's not documented, please reach out to our discussion forum and we'll do our best to help.
Remote APIs
The syntax for configuring remote APIs has changed slightly:
// Use a client credentials token
app.MapRemoteBffApiEndpoint("/api/client-token", "https://localhost:5010")
- .RequireAccessToken(TokenType.Client);
+ .WithAccessToken(RequiredTokenType.Client);
// Use the client token only if the user is logged in
app.MapRemoteBffApiEndpoint("/api/optional-user-token", "https://localhost:5010")
- .WithOptionalUserAccessToken();
+ .WithAccessToken(RequiredTokenType.UserOrNone); - The enum
TokenTypehas been renamed toRequiredTokenType. - The method to require the token type is renamed to
WithAccessToken() - Requesting an optional access token should not be done with the method
WithOptionalUserAccessToken()but withRequiredTokenType.UserOrNone
Configuring Token Types In YARP
The required token type configuration in yarp has also changed slightly. It uses the enum values from RequiredTokenType.
Extending The BFF
Simplified Wireup Without Explicit Authentication Setup
The V3 style of wireup still works, but BFF V4 comes with a newer style of wireup:
services.AddBff()
.WithDefaultOpenIdConnectOptions(options =>
{
options.Authority = "your authority";
options.ClientId = "your client id";
options.ClientSecret = "secret";
// ... other OpenID Connect options.
}
.WithDefaultCookieOptions(options => {
// The cookie options are automatically configured with recommended practices.
// However, you can change the config here.
};Adding this will automatically configure a Cookie and OpenID Connect flow.
Adding Multiple Frontends
You can statically add a list of frontends by calling the AddFrontends method.
.AddFrontends(
new BffFrontend(BffFrontendName.Parse("default-frontend"))
.WithIndexHtmlUrl(new Uri("https://localhost:5005/static/index.html")),
new BffFrontend(BffFrontendName.Parse("with-path"))
.WithOpenIdConnectOptions(opt =>
{
opt.ClientId = "bff.multi-frontend.with-path";
opt.ClientSecret = "secret";
})
.WithIndexHtmlUrl(new Uri("https://localhost:5005/static/index.html"))
.MappedToPath(LocalPath.Parse("/with-path")),
new BffFrontend(BffFrontendName.Parse("with-domain"))
.WithOpenIdConnectOptions(opt =>
{
opt.ClientId = "bff.multi-frontend.with-domain";
opt.ClientSecret = "secret";
})
.WithIndexHtmlUrl(new Uri("https://localhost:5005/static/index.html"))
.MappedToOrigin(Origin.Parse("https://app1.localhost:5005"))
.WithRemoteApis(
new RemoteApi(LocalPath.Parse("/api/user-token"), new Uri("https://localhost:5010")),
new RemoteApi(LocalPath.Parse("/api/client-token"), new Uri("https://localhost:5010"))
)Loading Configuration From IConfiguration
Loading configuration, including openid connect configuration from an IConfiguration is now supported:
services.AddBff().LoadConfiguration(bffConfig);Using this, you can configure your openid connect options, including secrets and configure the list of frontends. This also adds a file watcher, to automatically add / remove frontends from the config file.
See the type BffConfiguration to see what settings can be configured.
Index HTML Retrieval
It's fairly common to deploy your application in such a way to have the BFF be the first entrypoint for your application. It should serve an index.html that will bootstrap your frontend. However, your static content should be loaded from a CDN.
If you publish your frontend code to a cdn with absolute paths (for example by specifying a base path in your vite config), then all static content is loaded directly from the CDN.
You can configure the location of your Index HTML by specifying:
.WithIndexHtmlUrl(new Uri("https://localhost:5005/static/index.html"))IdentityServer 7.2.3
This is a patch release that fixes a regression where multiple WWW-authenticate headers where issued.
What's Changed
- Ensure WWW-Authenticate uses a single HTTP header by @khalidabuhakmeh in https://github.com/DuendeSoftware/products/pull/1998
Full Changelog: is-7.2.2...is-7.2.3
IdentityServer 7.2.2
This is a patch release that
- Hardens the default configuration of the sensitive values filters and
- Fixes mTLS binding so that port numbers can be used as part of mTLS domain
Sensitive Values Filter Defaults
hardens the security of the default configuration that controls the redaction in logs of parameters passed to the Pushed Authorization (PAR) and Authorize endpoint, ensuring that client secrets and client assertions are not logged by default.
In particular, the default value of AuthorizeRequestSensitiveValuesFilter and PushedAuthorizationSensitiveValuesFilter have been changed to both be ["client_secret", "client_assertion", "id_token_hint"].
PAR requests sometimes are handled by the same code path as authorize requests, so this makes both filters the same by default.
mTLS port number
The MtlsOptions.DomainName can now include a port number.
Detailed Changelog
- Harden default logging filters for PAR and Authorize endpoints (7.2) by @josephdecock in https://github.com/DuendeSoftware/products/pull/1978
- Respect port number in mTLS configuration by @josephdecock in https://github.com/DuendeSoftware/products/pull/1990
Full Changelog: is-7.2.1...is-7.2.2
IdentityServer 7.2.1
This is a patch release of IdentityServer that fixes a bug where a private_key_jwt client authentication token would be rejected if it had no typ header, even if strict validation of such tokens was not enabled.
What's Changed
- Handle no typ in private_key_jwt authentication by @josephdecock in https://github.com/DuendeSoftware/products/pull/1965
Templates 1.0.0
This is the version 1.0.0 release of a new templates package for Duende products.
New Template Package
The templates for Duende have been moved from Duende.IdentityServer.Templates to a new package called Duende.Templates to better reflect that these templates not only apply to Duende.IdentityServer, but also to Duende.BFF.
All new templates now have the shortname prefix duende-
Note, these templates can be installed side-by-side with the older Duende.IdentityServer.Templates, but we recommend uninstalling this version.
Duende BFF Templates
- Duende BFF Host using a Remote API (
duende-bff-remoteapi)- A backend-for-frontend (BFF) template that connects to a remote API.
- Duende BFF using a Local API (
duende-bff-localapi)- A BFF template that integrates with a local API.
- Duende BFF with Blazor Auto render mode enabled (
duende-bff-blazor)- A Blazor-based BFF template that demonstrates how to use blazor auto-rendering in a blazor bff application.
Duende IdentityServer Templates
- Duende IdentityServer Empty (
duende-is-empty)- A minimal IdentityServer setup for custom implementations.
- Duende IdentityServer Quickstart UI (
duende-is-ui)- This template contains a quickstart UI, that you can apply to an existing Duende.IdentityServer project.
- Duende IdentityServer with ASP.NET Core Identity (
duende-is-aspid)- IdentityServer integrated with ASP.NET Core Identity for user management.
- Duende IdentityServer with Entity Framework Storage (
duende-is-ef)- IdentityServer using Entity Framework for configuration and operational data storage.
- Duende IdentityServer with In-Memory Storage (
duende-is-inmem)- IdentityServer with an in-memory store for quick prototyping and testing.
Getting Started
To install the templates, run:
dotnet new install Duende.TemplatesTo install a package:
mkdir [ProjectName]
cd [ProjectName]
dotnet new [PackageName]For example:
mkdir My.BffProject
cd My.BffProject
dotnet new duende-bff-localapiUninstalling Duende.IdentityServer.Templates
To uninstall the deprecated version of Duende.IdentityServer.Templates:
dotnet new uninstall Duende.IdentityServer.TemplatesIdentityServer 7.2.0
IdentityServer 7.2 is a significant release that includes:
- Optional strict validation of
private_key_jwtaudiences, implementing RFC 7523 bis - Optional caching of the discovery endpoint
- Less log noise when issuing the
use_dpop_nonceresponse from the token endpoint - Bug fixes and optimizations
Upgrading
There are no breaking changes or schema updates required to upgrade from IdentityServer 7.1 to 7.2.
Upgrading from IdentityServer 7.2.0-preview.1
We have moved the StrictClientAssertionAudienceValidation option that was introduced in 7.2.0-preview.1 into a new Preview section of the options. This new section provides a mechanism for us to deliver new features more quickly, and gives us the flexibility to change implementation details, behavior, or the API surface. Users can opt in to preview features at their own discretion, with the understanding that we make a stronger commitment to API stability once a feature leaves preview. Our intent with Preview flags is to be able to iterate quickly while still providing stability.
We've decided to mark StrictClientAssertionAudienceValidation as a preview option since the formal specification that it is based on (RFC 7523 bis) has not yet been adopted by the IETF OAuth working group.
RFC 7523 bis
RFC 7523 bis is a proposed update to RFC 7523 in which two new requirements for private_key_jwt client assertions are proposed:
- That the audience (
audclaim) must be the issuer of the authorization server and must be a single string - That the type (
typheader) must be "client-authentication+jwt"
Similar strict audience validation requirements can be found in the FAPI 2.0 Profile.
The intent of the audience validation is to prevent certain academic attacks against OAuth ecosystems that include multiple Authorization Servers in which one of the Authorization Servers is compromised or malicious. The new type header value provides a mechanism to facilitate upgrades, because conforming clients that adopt the proposed changes will produce a token that can be easily distinguished by looking for the new type.
IdentityServer 7.2 includes preview support for RFC 7523 bis. Client applications can opt in to this support by setting the new type header; assertions that set the typ header to client-authentication+jwt always have their audience validated strictly. Other clients can continue to authenticate with private_key_jwts as they do today. IdentityServer can be configured to force clients to update by setting the option options.Preview.StrictClientAssertionAudienceValidation. When that flag is enabled, all private_key_jwt client assertions must set the typ to client-authentication+jwt, and must set their audience to the IdentityServer's issuer.
Discovery Document Caching
We've heard reports of cases where a high volume of requests to the discovery endpoint caused memory pressure and strain on server resources. This could happen in a solution with many clients calling the discovery endpoint, such as native (mobile) clients, SPA clients, or microservices that connect directly to the identity provider. It could also happen if misconfigured clients fail to cache the discovery response.
We’ve added a preview feature that allows you to cache the endpoint output using your distributed cache registration, with the default cache being an in-memory implementation. The cache is meant to reduce pressure when a sudden spike in requests occurs.
You must set the following property in your IdentityServerOptions instance to enable discovery document caching:
#pragma warning disable DUENDEPREVIEW001
pipeline.Options.Preview.EnableDiscoveryDocumentCache = true;
#pragma warning restore DUENDEPREVIEW001
pipeline.Options.Preview.DiscoveryDocumentCacheDuration = TimeSpan.FromMinutes(1);It's best to keep the cache time low if you utilize the CustomEntries element on the discovery document or implement a custom IDiscoveryResponseGenerator.
This feature is a step in optimizing Duende IdentityServer to utilize server resources and improve performance. More benchmarking and tuning will follow.
use_dpop_nonce Log Noise Reduction
One way to configure DPoP is to require a server-issued nonce value. A nonce prevents replay or pre-generation of the proof tokens used in DPoP by having the authorization server provide a nonce value that the client must include in its signatures. That nonce is provided to the client through a protocol error response.
In IdentityServer 7.1 and earlier, this raised the TokenIssuedFailureEvent because, technically, the token endpoint returns an error. However, this interaction is an expected part of the interaction between client and server. It isn’t an error in the usual sense of the word, and it can happen quite often, resulting in lots of noise in the logs. Therefore, we no longer raise the TokenIssuedFailureEvent when returning a server-generated DPoP nonce.
For those still interested in knowing these errors are occurring, we have added additional Debug log messages to help diagnose and troubleshoot your client implementations. Because these messages are low severity, you must explicitly enable them in your environments to see them. The existing OTel metrics that track token error responses are unchanged, as they don’t add noise to the logs.
Detailed changelog
- Revert Change Causing Unnecessary Cookie Re-Issue by @bhazen in https://github.com/DuendeSoftware/products/pull/1818
- Backported workflow changes from main to 7.1 by @bhazen in https://github.com/DuendeSoftware/products/pull/1821
- Removing redundant tag step in release workflow by @bhazen in https://github.com/DuendeSoftware/products/pull/1822
- Change where to expect artifacts during upload by @josephdecock in https://github.com/DuendeSoftware/products/pull/1823
- Merge 7.1.1 Changes Forward to 7.2.x by @bhazen in https://github.com/DuendeSoftware/products/pull/1840
- Add caching support for discovery documents with preview options by @khalidabuhakmeh in https://github.com/DuendeSoftware/products/pull/1843
- Introduce the
StrictClientAssertionAudienceValidationpreview feature by @StuFrankish in https://github.com/DuendeSoftware/products/pull/1860 - Fix incorrect 'for' attribute in userCode inputs by @khalidabuhakmeh in https://github.com/DuendeSoftware/products/pull/1712
- Fix two potential NREs by @maartenba in https://github.com/DuendeSoftware/products/pull/1731
- Use query-safe url fragment when returning an error by @bhazen in https://github.com/DuendeSoftware/products/pull/1733 (including community contributions from @aomader in https://github.com/DuendeSoftware/products/pull/1670)
- Use AsyncServiceScope in Background Services by @bhazen in https://github.com/DuendeSoftware/products/pull/1736
- Add option for strict validation of assertion audiences by @josephdecock in https://github.com/DuendeSoftware/products/pull/1737
- Fix XML documentation syntax errors by @maartenba in https://github.com/DuendeSoftware/products/pull/1730
- Do not issue TokenIssuedFailureEvent for use_dpop_nonce error by @bhazen in https://github.com/DuendeSoftware/products/pull/1739
- Avoid a string allocation in IsUri by @SimonCropp in https://github.com/DuendeSoftware/products/pull/1680
- Enable nullable in StringsExtensions by @SimonCropp in https://github.com/DuendeSoftware/products/pull/1679
- ThrowIfNullOrWhiteSpace for type in IdentityProvider by @SimonCropp in https://github.com/DuendeSoftware/products/pull/1675
- Optimize Resource constructors by @SimonCropp in https://github.com/DuendeSoftware/products/pull/1674
Duende BFF Security Framework V3.0
What's new?
Duende BFF Security Framework v3.0 is a significant release that includes:
- .NET 9 support
- Blazor support
- Several fixes and improvements
Blazor support
Microsoft's Blazor framework enables developers to build interactive web applications using C# and .NET, offering both server-side and client-side hosting models. However, implementing authentication in Blazor presents certain challenges. For example, in split-mode scenarios, where rendering is divided between server and client, managing authentication states consistently can be complex.
To address these issues, the new Backend for Frontend (BFF) framework provides comprehensive support for authentication in Blazor applications. The BFF pattern centralizes authentication logic on the server side, creating a secure environment for managing user identities and sessions. As with other browser based applications, the actual authentication logic is handled on the server by the Duende BFF Security Framework. On the client, the BFF makes sure that the authentication state is in sync with the session on the server.
Breaking changes
- Bff yarp proxy improvements #1734 (With many thanks to @ArturDorochowicz for bringing this issue to our attention and providing a solution direction)
- AddAddEntityFrameworkServerSideSessionsServices in Duende.Bff.EntityFramework/Configuration/BffBuilderExtensions.cs #1695
- Async GetUserClaims, GetManagementClaims #1702
- Consolidating ClaimRecord and ClaimLite #1697
Other fixes and improvements
- Prevent log warning when expected duplicate key constraint is violated. #1763
- Signout on refresh token expire #1803
- Bumped version of Duende.AccessTokenManagement to 3.2.0 #1804
Upgrading
If you rely on the default extension methods for wiring up the BFF, then V3 should be a drop-in replacement.
Upgrade guide
From v2.x => v3.x
If you rely on the default extension methods for wiring up the BFF, then V3 should be a drop-in replacement.
Migrating from custom implementations of IHttpMessageInvokerFactory
In Duende.BFF V2, there was an interface called IHttpMessageInvokerFactory. This class was responsible for creating
and wiring up yarp's HttpMessageInvoker. This interface has been removed in favor yarp's IForwarderHttpClientFactory.
One common scenario for creating a custom implementation of this class was for mocking the http client
during unit testing.
If you wish to inject a http handler for unit testing, you should now inject a custom IForwarderHttpClientFactory. For example:
// A Forwarder factory that forwards the messages to a message handler (which can be easily retrieved from a testhost)
public class BackChannelHttpMessageInvokerFactory(HttpMessageHandler backChannel)
: IForwarderHttpClientFactory
{
public HttpMessageInvoker CreateClient(ForwarderHttpClientContext context) =>
new HttpMessageInvoker(backChannel);
}
// Wire up the forwarder in your application's test host:
services.AddSingleton<IForwarderHttpClientFactory>(
new BackChannelHttpMessageInvokerFactory(_apiHost.Server.CreateHandler()));
Migrating from custom implementations IHttpTransformerFactory
The IHttpTransformerFactory was a way to globally configure the YARP tranform pipeline. In V3, the way that
the default endpoints.MapRemoteBffApiEndpoint() method builds up the YARP transform has been simplified
significantly. Most of the logic has been pushed down to the AccessTokenRequestTransform.
Here are common scenario's for implementing your own IHttpTransformerFactory and how to upgrade:
Replacing defaults
If you used a custom implementation of IHttpTransformerFactory to change the default behavior of MapRemoteBffApiEndpoint(),
for example to add additional transforms, then you can now inject a custom delegate into the di container:
services.AddSingleton<BffYarpTransformBuilder>(CustomDefaultYarpTransforms);
//...
// This is an example of how to add a response header to ALL invocations of MapRemoteBffApiEndpoint()
private void CustomDefaultBffTransformBuilder(string localpath, TransformBuilderContext context)
{
context.AddResponseHeader("added-by-custom-default-transform", "some-value");
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(localpath, context);
}
Another way of doing this is to create a custom extensionmethod MyCustomMapRemoteBffApiEndpoint() that wraps
the MapRemoteBffApiEndpoint() and use that everywhere in your application. This is a great way to add other defaults
that should apply to all endpoints, such as requiring a specific type of access token.
Configuring transforms for a single route
Another common usecase for overriding the IHttpTransformerFactory was to have a custom transform for a single route, by
applying a switch statement and testing for specific routes.
Now, there is an overload on the endpoints.MapRemoteBffApiEndpoint() that allows you to configure the pipeline directly:
endpoints.MapRemoteBffApiEndpoint(
"/local-path",
_apiHost.Url(),
context =>
{
// do something custom: IE: copy request headers
context.CopyRequestHeaders = true;
// wire up the default transformer logic
DefaultTransformers.DirectProxyWithAccessToken("/local-path", context);
})
// Continue with normal BFF configuration, for example, allowing optional user access tokens
.WithOptionalUserAccessToken();Removed method RemoteApiEndpoint.Map(localpath, apiAddress).
The Map method was no longer needed as most of the logic had been moved to either the MapRemoteBffApiEndpoint and the DefaultTransformers. The map method also wasn't very explicit about what it did and a number of test scenario's tried to verify if it wasn't called wrongly. You are now expected to call the method MapRemoteBffApiEndpoint. This method now has a nullable parameter that allows you to inject your own transformers.
AccessTokenRetrievalContext properties are now typed
The LocalPath and ApiAddress properties are now typed. They used to be strings. If you rely on these, for example for implementing
a custom IAccessTokenRetriever, then you should adjust their usage accordingly.
/// <summary>
/// The locally requested path.
/// </summary>
public required PathString LocalPath { get; set; }
/// <summary>
/// The remote address of the API.
/// </summary>
public required Uri ApiAddress { get; set; }
AddAddEntityFrameworkServerSideSessionsServices has been renamed to AddEntityFrameworkServerSideSessionsServices
If you used the method AddAddEntityFrameworkServerSideSessionsServices() in your code, please replace it with the corrected AddEntityFrameworkServerSideSessionsServices()
StateProviderPollingDelay and StateProviderPollingInterval have been split into separate options for WebAssembly and Server.
If you used BffBlazorOptions.StateProviderPollingInterval or BffBlazorOptions.StateProviderPollingDelay to configure different polling settings, you should now consider if this same setting applies to either Server, WASM or both. Set the appropriate properties accordingly.
IdentityServer 7.1.1
This is a patch release that fixes a bug that could cause sessions to expire instead of sliding.
What's Changed
- Revert Change Causing Unnecessary Cookie Re-Issue by @bhazen in https://github.com/DuendeSoftware/products/pull/1818
Duende BFF Security Framework V3 - Release Candidate 1
This is the first Release Candidate for the next version of the Duende BFF Security Framework V3.
What's new?
Duende BFF Security Framework v3.0 is a significant release that includes:
- .NET 9 support
- Blazor support
- Several fixes and improvements
Blazor support
Microsoft's Blazor framework enables developers to build interactive web applications using C# and .NET, offering both server-side and client-side hosting models. However, implementing authentication in Blazor presents certain challenges. For example, in split-mode scenarios, where rendering is divided between server and client, managing authentication states consistently can be complex.
To address these issues, the new Backend for Frontend (BFF) framework provides comprehensive support for authentication in Blazor applications. The BFF pattern centralizes authentication logic on the server side, creating a secure environment for managing user identities and sessions. As with other browser based applications, the actual authentication logic is handled on the server by the Duende BFF Security Framework. On the client, the BFF makes sure that the authentication state is in sync with the session on the server.
Breaking changes
- Bff yarp proxy improvements #1734 (With many thanks to @ArturDorochowicz for bringing this issue to our attention and providing a solution direction)
- AddAddEntityFrameworkServerSideSessionsServices in Duende.Bff.EntityFramework/Configuration/BffBuilderExtensions.cs #1695
- Async GetUserClaims, GetManagementClaims #1702
- Consolidating ClaimRecord and ClaimLite #1697
Other fixes and improvements
- Prevent log warning when expected duplicate key constraint is violated. #1763
- Signout on refresh token expire #1803
- Bumped version of Duende.AccessTokenManagement to 3.2.0 #1804
Upgrading
If you rely on the default extension methods for wiring up the BFF, then V3 should be a drop-in replacement.
Upgrade guide
From v2.x => v3.x
If you rely on the default extension methods for wiring up the BFF, then V3 should be a drop-in replacement.
Migrating from custom implementations of IHttpMessageInvokerFactory
In Duende.BFF V2, there was an interface called IHttpMessageInvokerFactory. This class was responsible for creating
and wiring up yarp's HttpMessageInvoker. This interface has been removed in favor yarp's IForwarderHttpClientFactory.
One common scenario for creating a custom implementation of this class was for mocking the http client
during unit testing.
If you wish to inject a http handler for unit testing, you should now inject a custom IForwarderHttpClientFactory. For example:
// A Forwarder factory that forwards the messages to a message handler (which can be easily retrieved from a testhost)
public class BackChannelHttpMessageInvokerFactory(HttpMessageHandler backChannel)
: IForwarderHttpClientFactory
{
public HttpMessageInvoker CreateClient(ForwarderHttpClientContext context) =>
new HttpMessageInvoker(backChannel);
}
// Wire up the forwarder in your application's test host:
services.AddSingleton<IForwarderHttpClientFactory>(
new BackChannelHttpMessageInvokerFactory(_apiHost.Server.CreateHandler()));
Migrating from custom implementations IHttpTransformerFactory
The IHttpTransformerFactory was a way to globally configure the YARP tranform pipeline. In V3, the way that
the default endpoints.MapRemoteBffApiEndpoint() method builds up the YARP transform has been simplified
significantly. Most of the logic has been pushed down to the AccessTokenRequestTransform.
Here are common scenario's for implementing your own IHttpTransformerFactory and how to upgrade:
Replacing defaults
If you used a custom implementation of IHttpTransformerFactory to change the default behavior of MapRemoteBffApiEndpoint(),
for example to add additional transforms, then you can now inject a custom delegate into the di container:
services.AddSingleton<BffYarpTransformBuilder>(CustomDefaultYarpTransforms);
//...
// This is an example of how to add a response header to ALL invocations of MapRemoteBffApiEndpoint()
private void CustomDefaultBffTransformBuilder(string localpath, TransformBuilderContext context)
{
context.AddResponseHeader("added-by-custom-default-transform", "some-value");
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(localpath, context);
}
Another way of doing this is to create a custom extensionmethod MyCustomMapRemoteBffApiEndpoint() that wraps
the MapRemoteBffApiEndpoint() and use that everywhere in your application. This is a great way to add other defaults
that should apply to all endpoints, such as requiring a specific type of access token.
Configuring transforms for a single route
Another common usecase for overriding the IHttpTransformerFactory was to have a custom transform for a single route, by
applying a switch statement and testing for specific routes.
Now, there is an overload on the endpoints.MapRemoteBffApiEndpoint() that allows you to configure the pipeline directly:
endpoints.MapRemoteBffApiEndpoint(
"/local-path",
_apiHost.Url(),
context =>
{
// do something custom: IE: copy request headers
context.CopyRequestHeaders = true;
// wire up the default transformer logic
DefaultTransformers.DirectProxyWithAccessToken("/local-path", context);
})
// Continue with normal BFF configuration, for example, allowing optional user access tokens
.WithOptionalUserAccessToken();Removed method RemoteApiEndpoint.Map(localpath, apiAddress).
The Map method was no longer needed as most of the logic had been moved to either the MapRemoteBffApiEndpoint and the DefaultTransformers. The map method also wasn't very explicit about what it did and a number of test scenario's tried to verify if it wasn't called wrongly. You are now expected to call the method MapRemoteBffApiEndpoint. This method now has a nullable parameter that allows you to inject your own transformers.
AccessTokenRetrievalContext properties are now typed
The LocalPath and ApiAddress properties are now typed. They used to be strings. If you rely on these, for example for implementing
a custom IAccessTokenRetriever, then you should adjust their usage accordingly.
/// <summary>
/// The locally requested path.
/// </summary>
public required PathString LocalPath { get; set; }
/// <summary>
/// The remote address of the API.
/// </summary>
public required Uri ApiAddress { get; set; }
AddAddEntityFrameworkServerSideSessionsServices has been renamed to AddEntityFrameworkServerSideSessionsServices
If you used the method AddAddEntityFrameworkServerSideSessionsServices() in your code, please replace it with the corrected AddEntityFrameworkServerSideSessionsServices()
StateProviderPollingDelay and StateProviderPollingInterval have been split into separate options for WebAssembly and Server.
If you used BffBlazorOptions.StateProviderPollingInterval or BffBlazorOptions.StateProviderPollingDelay to configure different polling settings, you should now consider if this same setting applies to either Server, WASM or both. Set the appropriate properties accordingly.