You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
IdentityServer 7 includes support for .NET 8, pushed authorization requests, OpenTelemetry Metrics, improvements to token cleanup, and many other fixes and improvements.
.NET 8
IdentityServer now targets .NET 8. In addition to keeping IdentityServer implementations covered by Microsoft support, new features in .NET 8 enabled several improvements to IdentityServer. See #1337 for more details on the core update, and the item below for a related update that makes use of a new .NET 8 API.
IdentityServer now supports Pushed Authorization Requests. Pushed Authorization Requests (PAR) is a relatively new OAuth standard that improves the security of OAuth and OIDC flows by moving authorization parameters from the front channel to the back channel (that is, from redirect URLs in the browser to direct machine to machine http calls on the back end). See #1424.
OpenTelemetry Metrics
IdentityServer's support for OpenTelemetry now includes support for metrics. OpenTelemetry measurements are now made where we have historically raised our custom events. While IdentityServer will continue to raise those custom events, we think that OpenTelemetry offers significant advantages (open standards and a large ecosystem of tooling), and we intend to emphasize OpenTelemetry in our future work related to observability. See #1456.
Reusable Refresh Tokens
Refresh tokens are now reusable by default. Rotated refresh tokens have historically been encouraged (and been our default), however more recent guidance from the IETF and our own experience have shown that rotation is not usually helpful from a security point of view but is actively harmful to the user experience and produces greater load on the data store.
Rotation of refresh tokens often does not improve their security because a sophisticated attacker can observe the rotation happening while the user is active, and only make use of the final token after the user is no longer active. See OAuth for Browser Based Apps for more details on this sort of attack.
Rotation harms the user experience, because if the token is rotated, but the network response with the new token fails, the user will have to log in again.
Rotation adds pressure on the data store because each time the token rotates, the old record must be updated and a new record written.
Given all these considerations, we have changed our default for RefreshTokenUsage to ReUse. Also see #1500.
Token Cleanup Job Improvements
The token cleanup job has historically been the cause of database contention, especially in load-balanced environments, as multiple instances of the job each try to update the table. This release includes a new implementation of the cleanup job which uses EntityFramework's execute delete api to improve performance as well as randomizing the initial startup time of the cleanup job, to help reduce the amount of concurrency across instances. See #1501.
The server-side session entity in Duende.IdentityServer.EntityFramework now uses a 64-bit long as its primary key (previously was a 32-bit int). See Change ServerSideSession.Id to long #1463.
Two new properties have been added to the client model for PAR support. See Add support for PAR #1424.
Client.RequirePushedAuthorization is a new boolean property that controls if this client requires PAR. PAR is required if either the global configuration is enabled or if the client's flag is enabled (this can't be used to opt out of the global configuration). It is safe to initialize this column to false for existing clients, which will mean that the global configuration will be used.
Client.PushedAuthorizationLifetime is a new nullable integer property that controls the lifetime of pushed authorization requests (in seconds) for a client. If this lifetime is set, it takes precedence over the global configuration. It is safe to initialize this column to null for existing clients, which means the global configuration is used.
A new table has been added to store pushed authorization requests. This new table contains a hashed identifier, the pushed parameters (as a string, serialized and data protected), and the expiration time of the request. See Add support for PAR #1424.
Only impacts particular customizations or edge cases
The DefaultCorsPolicyService now depends on the IConfigurationDbContext directly, instead of taking a dependency on the IServiceProvider and resolving that DbContext from it. If you have a customized CORS implementation that derives from the DefaultCorsPolicyService, you need to update the constructor of your derived class to use the IConfigurationDbContext. See Remove IServiceProvider from CorsPolicyService #1239.
The DPoPProofValidatonContext has been refactored. Instead of the Client property, we now put the relevant details (expiration validation mode and clock skew) directly in the context. We also have added the HTTP method and URL to the context. If you have a custom implementation of the IDPoPProofValidator or a class that derives from the DefaultDPoPProofValidator, update your usage of the context appropriately. See Add DPoP support to our AddLocalApi access token validation #1338.
The DefaultTokenService no longer includes an IHttpContextAccessor. This member was unused by the default implementation and marked as obsolete. Customizations that derive from the DefaultTokenService no longer need to pass the accessor to the base constructor. If such a customization needs the accessor, add it to the derived class. See Cleanup deprecated code and TODOs #1457.
The ValidatedAuthorizeRequest.RequestedResourceIndiators property was misspelled and has been renamed RequestedResourceIndicators. See Cleanup deprecated code and TODOs #1457.
The reference token store now includes the session id when revoking reference tokens. Implementors of IReferenceTokenStore should update their implementation of token revocation to include the session id. See use session id when revoking reference tokens for refresh token #1321.
Invalid prompt modes now cause validation errors that result in an HTTP 400 (Bad Request). Previously, invalid prompt modes were ignored. This complies with updates to the OpenID Connect specification. See return error for unknown prompt values on authorize endpoint #1331.
The IHttpContextAccessor in the EndSessionRequestValidator is unused and has been marked as obsolete. It will be removed in a future version. See Cleanup deprecated code and TODOs #1457.
Previously Deprecated, Now Removed
The obsolete IdentityServerOrigin constant has been removed.
Several obsolete extension methods on HttpContext have been removed. These methods are replaced by methods in IServerUrls and IIssuerNameService. See Cleanup deprecated code and TODOs #1457
HttpContext.GetSchemeSupportsSignOutAsync is replaced by IAuthenticationHandlerProvider.GetHandlerAsync (you will also need to check if the handler implements IAuthenticationSignOutHandler).
HttpContext.GetIdentityServerOrigin and HttpContext.SetIdentityServerOrigin are replaced by IServerUrls.Origin.
HttpContext.GetIdentityServerBasePath and HttpContext.SetIdentityServerBasePath are replaced by IServerUrls.BasePath.
GetIdentityServerHost is replaced by IServerUrls.Origin
GetIdentityServerBaseUrl is replaced by IServerUrls.BaseUrl
GetIdentityServerRelativeUrl is replaced by IServerUrls.GetIdentityServerRelativeUrl
GetIdentityServerIssuerUri is replaced by IIssuerNameService.GetCurrentAsync
RedirectToAbsoluteUrl is replaced by redirecting to a call to IServerUrls.GetAbsoluteUrl.
The obsolete IPrincipal.GetName and IIdentity.GetName extension methods have been removed. Use ClaimsPrincipal.GetDisplayName instead. See Cleanup deprecated code and TODOs #1457.
The obsolete ResourceValidationRequest.IncludeNonIsolatedApiResources has been removed. This flag was no longer used. See Cleanup deprecated code and TODOs #1457.
Unlikely to impact anyone
The KeyManagementOptions.SigningAlgorithms is now an ICollection rather than an IEnumerable. If you are configuring signing algorithms using code, and setting the SigningAlgorithms to some type that implements IEnumerable but not ICollection, then you must change the type that you are using. In practice, we expect everyone uses a list or array (which are both ICollections). See Fix KeyManagementOptions binding #1375.
The value of the constant IdentityServerAuthenticationType has changed from "IdentityServer4" to "Duende.IdentityServer". This constant is used as the value of the authentication type within the ClaimsIdentity that IdentityServer constructs. The authentication type's value is never used by IdentityServer or ASP.NET, so this is unlikely to impact anyone. It is also the name of the default cors policy created by IdentityServer. This could theoretically impact you if you have a CORS policy named "Duende.IdentityServer", as the new name now conflicts. See Cleanup deprecated code and TODOs #1457.
New Configuration Options
PAR
IdentityServerOptions now includes the PushedAuthorization property to configure PAR.
PushedAuthorizationOptions.Required causes par to be required globally. This defaults to false.
PushedAuthorizationOptions.Lifetime controls the lifetime of pushed authorization requests. The pushed authorization request's lifetime begins when the request to the PAR endpoint is received, and is validated until the authorize endpoint returns a response to the client application. Note that user interaction, such as entering credentials or granting consent, may need to occur before the authorize endpoint can do so. Setting the lifetime too low will likely cause login failures for interactive users, if pushed authorization requests expire before those users complete authentication. Some security profiles, such as the FAPI 2.0 Security Profile recommend an expiration within 10 minutes to prevent attackers from pre-generating requests. To balance these constraints, this lifetime defaults to 10 minutes.
PushedAuthorizationOptions.AllowUnregisteredPushedRedirectUris controls whether clients may use redirect uris that were not previously registered. This is a relaxation of security guidance that is specifically allowed by the PAR specification because the pushed authorization requests are authenticated. It defaults to false.
The Client configuration object now includes two new properties to configure PAR on a per-client basis.
Client.RequirePushedAuthorization controls if this client requires PAR. PAR is required if either the global configuration is enabled or if the client's flag is enabled (this can't be used to opt out of the global configuration). This defaults to false, which means the global configuration will be used.
Client.PushedAuthorizationLifetime controls the lifetime of pushed authorization requests for a client. If this lifetime is set, it takes precedence over the global configuration. This defaults to null, which means the global configuration is used.
The EndpointOptions now includes a new flag to enable or disable the PAR endpoint: EnablePushedAuthorizationEndpoint, which defaults to true.
Token Cleanup
OperationalStoreOptions.FuzzTokenCleanupStart controls if the cleanup job's initial startup time will be randomized to reduce the amount of database contention when multiple cleanup jobs run at the same time. Defaults to true.
Other Improvements
Protocol endpoints use the new interface IHttpResponseWriter to write their http responses. This facilitates customization, when you need to control the way that http responses are written. This change was made in a way that was designed to be backwards compatible. Any custom IEndpointResult or IEndpointHandler should still work the way they used to. See Support response generators for the endpoint results #1342 and Rename result generators #1450.
Ease extension of DCR using protected properties. Customizations that derive from the default DCR validator, request processor, and response generator now have access to the dependencies used in the default implementation. See Ease extension of DCR classes with protected props #1464
The processed and original prompt modes are now exposed on the ValidatedAuthorizeRequest. The prompt modes have historically been mutated as we use them, and the processed and original prompt modes have been tracked internally. We now expose these additional properties to facilitate customization that relies on the prompt modes. See Expose processed and original prompt modes #1453.
The license object is now public and available in the DI system. This allows for easier license status checks, UI that indicates that the license status, etc. See Make License available in DI #1319.
The CIBA request, validation, storage, and response models now all include a dictionary of custom properties to facilitate custom request and response parameters. See CIBA Customization Extensibility Points #1497.
Remove the raw exception from unhandled exception events. These exceptions don't serialize cleanly and we already capture the exception message as part of the event. See Remove raw exception from unhandled exception event #1363.
We published the nuget, but the above release notes should get updated manually with the more formal descriptions that we've been collecting in this thread. Thanks!
IdentityServer 7 includes support for .NET 8, pushed authorization requests, OpenTelemetry Metrics, improvements to token cleanup, and many other fixes and improvements.
.NET 8
IdentityServer now targets .NET 8. In addition to keeping IdentityServer implementations covered by Microsoft support, new features in .NET 8 enabled several improvements to IdentityServer. See #1337 for more details on the core update, and the item below for a related update that makes use of a new .NET 8 API.
TimeProvider
based clock abstraction improves the granularity of the clock and make code that depends on it easier to test. See Use new clock abstraction #1341.Pushed Authorization Requests
IdentityServer now supports Pushed Authorization Requests. Pushed Authorization Requests (PAR) is a relatively new OAuth standard that improves the security of OAuth and OIDC flows by moving authorization parameters from the front channel to the back channel (that is, from redirect URLs in the browser to direct machine to machine http calls on the back end). See #1424.
OpenTelemetry Metrics
IdentityServer's support for OpenTelemetry now includes support for metrics. OpenTelemetry measurements are now made where we have historically raised our custom events. While IdentityServer will continue to raise those custom events, we think that OpenTelemetry offers significant advantages (open standards and a large ecosystem of tooling), and we intend to emphasize OpenTelemetry in our future work related to observability. See #1456.
Reusable Refresh Tokens
Refresh tokens are now reusable by default. Rotated refresh tokens have historically been encouraged (and been our default), however more recent guidance from the IETF and our own experience have shown that rotation is not usually helpful from a security point of view but is actively harmful to the user experience and produces greater load on the data store.
Rotation of refresh tokens often does not improve their security because a sophisticated attacker can observe the rotation happening while the user is active, and only make use of the final token after the user is no longer active. See OAuth for Browser Based Apps for more details on this sort of attack.
Rotation harms the user experience, because if the token is rotated, but the network response with the new token fails, the user will have to log in again.
Rotation adds pressure on the data store because each time the token rotates, the old record must be updated and a new record written.
Given all these considerations, we have changed our default for
RefreshTokenUsage
toReUse
. Also see #1500.Token Cleanup Job Improvements
The token cleanup job has historically been the cause of database contention, especially in load-balanced environments, as multiple instances of the job each try to update the table. This release includes a new implementation of the cleanup job which uses EntityFramework's execute delete api to improve performance as well as randomizing the initial startup time of the cleanup job, to help reduce the amount of concurrency across instances. See #1501.
Breaking Changes
Likely to impact most implementations
Duende.IdentityServer.EntityFramework
now uses a 64-bit long as its primary key (previously was a 32-bit int). See Change ServerSideSession.Id to long #1463.Client.RequirePushedAuthorization
is a new boolean property that controls if this client requires PAR. PAR is required if either the global configuration is enabled or if the client's flag is enabled (this can't be used to opt out of the global configuration). It is safe to initialize this column to false for existing clients, which will mean that the global configuration will be used.Client.PushedAuthorizationLifetime
is a new nullable integer property that controls the lifetime of pushed authorization requests (in seconds) for a client. If this lifetime is set, it takes precedence over the global configuration. It is safe to initialize this column tonull
for existing clients, which means the global configuration is used.Only impacts particular customizations or edge cases
The
DefaultCorsPolicyService
now depends on theIConfigurationDbContext
directly, instead of taking a dependency on theIServiceProvider
and resolving that DbContext from it. If you have a customized CORS implementation that derives from theDefaultCorsPolicyService
, you need to update the constructor of your derived class to use theIConfigurationDbContext
. See Remove IServiceProvider from CorsPolicyService #1239.The
DPoPProofValidatonContext
has been refactored. Instead of theClient
property, we now put the relevant details (expiration validation mode and clock skew) directly in the context. We also have added the HTTP method and URL to the context. If you have a custom implementation of theIDPoPProofValidator
or a class that derives from theDefaultDPoPProofValidator
, update your usage of the context appropriately. See Add DPoP support to our AddLocalApi access token validation #1338.The
DefaultTokenService
no longer includes anIHttpContextAccessor
. This member was unused by the default implementation and marked as obsolete. Customizations that derive from theDefaultTokenService
no longer need to pass the accessor to the base constructor. If such a customization needs the accessor, add it to the derived class. See Cleanup deprecated code and TODOs #1457.The
ValidatedAuthorizeRequest.RequestedResourceIndiators
property was misspelled and has been renamedRequestedResourceIndicators
. See Cleanup deprecated code and TODOs #1457.The reference token store now includes the session id when revoking reference tokens. Implementors of
IReferenceTokenStore
should update their implementation of token revocation to include the session id. See use session id when revoking reference tokens for refresh token #1321.Invalid prompt modes now cause validation errors that result in an HTTP 400 (Bad Request). Previously, invalid prompt modes were ignored. This complies with updates to the OpenID Connect specification. See return error for unknown prompt values on authorize endpoint #1331.
Newly Deprecated
IAuthorizationParametersMessageStore
is deprecated. PAR is a more robust/standardized approach to get similar benefits. See Discourage IAuthorizationParametersMessageStore #1462.The
IHttpContextAccessor
in theEndSessionRequestValidator
is unused and has been marked as obsolete. It will be removed in a future version. See Cleanup deprecated code and TODOs #1457.Previously Deprecated, Now Removed
IdentityServerOrigin
constant has been removed.HttpContext
have been removed. These methods are replaced by methods inIServerUrls
andIIssuerNameService
. See Cleanup deprecated code and TODOs #1457HttpContext.GetSchemeSupportsSignOutAsync
is replaced byIAuthenticationHandlerProvider.GetHandlerAsync
(you will also need to check if the handler implementsIAuthenticationSignOutHandler
).HttpContext.GetIdentityServerOrigin
andHttpContext.SetIdentityServerOrigin
are replaced byIServerUrls.Origin
.HttpContext.GetIdentityServerBasePath
andHttpContext.SetIdentityServerBasePath
are replaced byIServerUrls.BasePath
.GetIdentityServerHost
is replaced byIServerUrls.Origin
GetIdentityServerBaseUrl
is replaced byIServerUrls.BaseUrl
GetIdentityServerRelativeUrl
is replaced byIServerUrls.GetIdentityServerRelativeUrl
GetIdentityServerIssuerUri
is replaced byIIssuerNameService.GetCurrentAsync
RedirectToAbsoluteUrl
is replaced by redirecting to a call toIServerUrls.GetAbsoluteUrl
.IUserSessionExtensions
interface has been removed. See Cleanup deprecated code and TODOs #1457.IPrincipal.GetName
andIIdentity.GetName
extension methods have been removed. UseClaimsPrincipal.GetDisplayName
instead. See Cleanup deprecated code and TODOs #1457.ResourceValidationRequest.IncludeNonIsolatedApiResources
has been removed. This flag was no longer used. See Cleanup deprecated code and TODOs #1457.Unlikely to impact anyone
The
KeyManagementOptions.SigningAlgorithms
is now anICollection
rather than anIEnumerable
. If you are configuring signing algorithms using code, and setting theSigningAlgorithms
to some type that implementsIEnumerable
but notICollection
, then you must change the type that you are using. In practice, we expect everyone uses a list or array (which are both ICollections). See Fix KeyManagementOptions binding #1375.The value of the constant
IdentityServerAuthenticationType
has changed from "IdentityServer4" to "Duende.IdentityServer". This constant is used as the value of the authentication type within the ClaimsIdentity that IdentityServer constructs. The authentication type's value is never used by IdentityServer or ASP.NET, so this is unlikely to impact anyone. It is also the name of the default cors policy created by IdentityServer. This could theoretically impact you if you have a CORS policy named "Duende.IdentityServer", as the new name now conflicts. See Cleanup deprecated code and TODOs #1457.New Configuration Options
PAR
IdentityServerOptions
now includes thePushedAuthorization
property to configure PAR.PushedAuthorizationOptions.Required
causes par to be required globally. This defaults tofalse
.PushedAuthorizationOptions.Lifetime
controls the lifetime of pushed authorization requests. The pushed authorization request's lifetime begins when the request to the PAR endpoint is received, and is validated until the authorize endpoint returns a response to the client application. Note that user interaction, such as entering credentials or granting consent, may need to occur before the authorize endpoint can do so. Setting the lifetime too low will likely cause login failures for interactive users, if pushed authorization requests expire before those users complete authentication. Some security profiles, such as the FAPI 2.0 Security Profile recommend an expiration within 10 minutes to prevent attackers from pre-generating requests. To balance these constraints, this lifetime defaults to 10 minutes.PushedAuthorizationOptions.AllowUnregisteredPushedRedirectUris
controls whether clients may use redirect uris that were not previously registered. This is a relaxation of security guidance that is specifically allowed by the PAR specification because the pushed authorization requests are authenticated. It defaults tofalse
.Client
configuration object now includes two new properties to configure PAR on a per-client basis.Client.RequirePushedAuthorization
controls if this client requires PAR. PAR is required if either the global configuration is enabled or if the client's flag is enabled (this can't be used to opt out of the global configuration). This defaults tofalse
, which means the global configuration will be used.Client.PushedAuthorizationLifetime
controls the lifetime of pushed authorization requests for a client. If this lifetime is set, it takes precedence over the global configuration. This defaults tonull
, which means the global configuration is used.EndpointOptions
now includes a new flag to enable or disable the PAR endpoint:EnablePushedAuthorizationEndpoint
, which defaults totrue
.Token Cleanup
OperationalStoreOptions.FuzzTokenCleanupStart
controls if the cleanup job's initial startup time will be randomized to reduce the amount of database contention when multiple cleanup jobs run at the same time. Defaults totrue
.Other Improvements
IHttpResponseWriter
to write their http responses. This facilitates customization, when you need to control the way that http responses are written. This change was made in a way that was designed to be backwards compatible. Any customIEndpointResult
orIEndpointHandler
should still work the way they used to. See Support response generators for the endpoint results #1342 and Rename result generators #1450.ValidatedAuthorizeRequest
. The prompt modes have historically been mutated as we use them, and the processed and original prompt modes have been tracked internally. We now expose these additional properties to facilitate customization that relies on the prompt modes. See Expose processed and original prompt modes #1453.IdentityServerEntityFramework
template now supports theInitiateLoginUri
client property. See add InitiateLoginUri to EF admin UI code #1314.IdentityServerTools
class now implements the newIIdentityServerTools
interface, to facilitate testing. See Add interface for IdentityServerTools #1454.ServerSideSideSessionRefreshTokenService.ValidateRefreshTokenAsync
is now a virtual method, to facilitate customization. See Make ValidateRefreshTokenAsync virtual #1488.ErrorMessage
class. See Include Activity Id in ErrorMessage #1494.Bug Fixes
KeyManagementOptions
to be bound from appsettings.json or other config sources. See Fix KeyManagementOptions binding #1375.invalid_response_type
toinvalid_request
, to better conform to RFC 6749. See Return invalid_request when no response_type is provided #1423.The text was updated successfully, but these errors were encountered: