Releases: openiddict/openiddict-core
6.0.0-preview3
This release introduces the following changes:
-
The existing
IOpenIddictAuthorizationManager.FindAsync(...)
andIOpenIddictTokenManager.FindAsync(...)
overloads have been merged and replaced by a single method where all the parameters are now optional (for instance, if a nullsubject
value is specified when callingIOpenIddictAuthorizationManager.FindAsync(...)
, the returned collection will contain authorizations for all users). -
New
IOpenIddictAuthorizationManager.RevokeAsync(...)
andIOpenIddictTokenManager.RevokeAsync(...)
APIs have been introduced to allow easily revoking authorizations or tokens associated based on specific parameters. E.g:
// Revoke all the active access tokens attached to the user [email protected].
await _tokenManager.RevokeAsync(subject: "[email protected]", client: null, status: Statuses.Active, type: TokenTypeHints.AccessToken);
6.0.0-preview2
This release introduces the following changes:
-
OpenIddict 6.0 preview 2 was updated to reference the .NET 9.0 RC2 packages on .NET 9.0.
-
The
OpenIddict.MongoDb
andOpenIddict.MongoDb.Models
packages now referenceMongoDB.Driver
andMongoDB.Bson
3.0.0 and are now strong-named.
Important
The third iteration of the C# MongoDB driver no longer supports .NET Standard 2.0 and requires .NET Framework 4.7.2 as the minimum version: OpenIddict users relying on the MongoDB integration and using the OpenIddict.MongoDb
or OpenIddict.MongoDb.Models
packages in projects targeting .NET Standard 2.0 or .NET Framework < 4.7.2 will need to update their projects when bumping OpenIddict to 6.0 preview 2.
- A new "claims issuer" option has been added to the client and validation stacks to allow controlling the value OpenIddict uses to populate the
Claim.Issuer
andClaim.OriginalIssuer
properties. This option is specially useful when using the OpenIddict client in legacy ASP.NET 4.6.2+ applications using ASP.NET Identity, since theClaim.Issuer
property is directly reflected in the user interface:
options.AddRegistration(new OpenIddictClientRegistration
{
// ...
Issuer = new Uri("https://localhost:44395/", UriKind.Absolute),
ClaimsIssuer = "Local authorization server"
});
options.UseWebProviders()
.AddActiveDirectoryFederationServices(options =>
{
// ...
options.SetClaimsIssuer("Contoso");
});
Important
To simplify migrating from the aspnet-contrib providers, the OpenIddict client now uses OpenIddictClientRegistration.ProviderName
as the first fallback value when OpenIddictClientRegistration.ClaimsIssuer
is not explicitly set (which is consistent with the pattern used in the OAuth 2.0-based social providers developed by Microsoft and the community).
If no provider name was set, the issuer URI is used as the claims issuer, as in previous versions.
- To be consistent with the new
prompt values
name used in OpenIddict 6.0 preview 1, theGetPrompts()
andHasPrompt()
extension have been renamed toGetPromptValues()
andHasPromptValue()
.
6.0.0-preview1
This release introduces the following changes:
-
OpenIddict 6.0 preview 1 now targets .NET 9.0 and references the .NET 9.0 RC1 packages on .NET 9.0 and higher.
-
The .NET 7.0 and .NET Framework 4.6.1 TFMs have been removed as these versions are no longer supported by Microsoft.
Important
While most OpenIddict 6.0 packages can still be used on these versions thanks to their .NET Standard 2.0 or 2.1 TFMs, doing that is strongly discouraged and users are instead encouraged to migrate to .NET 8.0 and .NET Framework 4.6.2 (or higher).
- Some of the server endpoints have been renamed in OpenIddict 6.0 to be more specific or more closely match the official names, which should reduce ambiguities and make migrating from other OAuth 2.0/OIDC stacks to OpenIddict easier:
Cryptography endpoint
->JSON Web Key Set endpoint
.Device endpoint
->Device authorization endpoint
.Logout endpoint
->End-session endpoint
.Userinfo endpoint
->UserInfo endpoint
.Verification endpoint
->End-user verification endpoint
.
Note
All the constants, builder methods, events and event handlers used by the OpenIddict client, core, server and validation stacks have been entirely updated to use the new names.
In most cases, reacting to this breaking change should be limited to just changing a few lines in your Startup
file:
OpenIddict 5.x | OpenIddict 6.x |
---|---|
options.SetCryptographyEndpointUris() |
options.SetJsonWebKeySetEndpointUris() |
options.SetDeviceEndpointUris() |
options.SetDeviceAuthorizationEndpointUris() |
options.SetLogoutEndpointUris() |
options.SetEndSessionEndpointUris() |
options.SetUserinfoEndpointUris() |
options.SetUserInfoEndpointUris() |
options.SetVerificationEndpointUris() |
options.SetEndUserVerificationEndpointUris() |
OpenIddict 5.x | OpenIddict 6.x |
---|---|
options.AllowDeviceCodeFlow() |
options.AllowDeviceAuthorizationFlow() |
OpenIddict 5.x | OpenIddict 6.x |
---|---|
options.EnableLogoutEndpointPassthrough() |
options.EnableEndSessionEndpointPassthrough() |
options.EnableUserinfoEndpointPassthrough() |
options.EnableUserInfoEndpointPassthrough() |
options.EnableVerificationEndpointPassthrough() |
options.EnableEndUserVerificationEndpointPassthrough() |
OpenIddict 5.x | OpenIddict 6.x |
---|---|
OpenIddictConstants.Permissions.Endpoints.Device |
OpenIddictConstants.Permissions.Endpoints.DeviceAuthorization |
OpenIddictConstants.Permissions.Endpoints.Logout |
OpenIddictConstants.Permissions.Endpoints.EndSession |
Tip
While not mandatory (as the permissions containing the old endpoint names are still fully functional in 6.x for backward compatibility), you can also update your applications table/database to use the new constant values (i.e ept:device_authorization
and ept:end_session
instead of ept:device
and ept:logout
).
- A whole new client authentication method negotiation logic was introduced in the OpenIddict client. As part of this change, complete support for mTLS in the client stack was also added to allow integrating with identity providers that require using
tls_client_auth
orself_signed_tls_client_auth
.
Note
If your X.509 client certificate - self-issued or not - includes the recommended "client authentication" extended key usage, you can directly attach it to OpenIddictClientRegistration.SigningCredentials
: in this case, it will be automatically used by OpenIddict if the remote server supports tls_client_auth
or self_signed_tls_client_auth
. If it doesn't, OpenIddict will automatically use the private key it contains to build a client assertion if the server supports private_key_jwt
.
options.AddRegistration(new OpenIddictClientRegistration
{
// ...
SigningCredentials =
{
new X509SigningCredentials(certificate)
}
});
If your client certificate doesn't include the "client authentication" extended key usage, OpenIddict won't automatically use it for mTLS-based authentication. In this case, you'll need to use the OpenIddictClientSystemNetHttpBuilder.SetSelfSignedTlsClientAuthenticationCertificateSelector()
or OpenIddictClientSystemNetHttpBuilder.SetTlsClientAuthenticationCertificateSelector()
APIs to register a custom certificate selector.
Tip
Web providers known to support mTLS - like Keycloak, that supports tls_client_auth
but not self_signed_tls_client_auth
- or client assertions now offer options.SetSigningCertificate()
and/or options.SetSigningKey()
APIs that can be used to easily register a certificate/key:
options.UseWebProviders()
.AddKeycloak(options =>
{
options.SetClientId("client_id")
.SetSigningCertificate(certificate)
.SetRedirectUri("callback/login/keycloak");
});
-
For consistency, mTLS support was also added to the validation stack for introspection requests sent to a server implementation that offers mTLS support.
-
New
RevokeByApplicationIdAsync()
/RevokeBySubjectAsync()
APIs modeled after the existingRevokeByAuthorizationIdAsync()
API have been added to the authorization/token managers/stores to allow revoking authorizations and tokens based on a given application identifier or user identifier more efficiently. -
The OpenIddict server now fully supports the Initiating User Registration via OpenID Connect specification: it will now validate the
prompt
parameter to ensure the value is supported and return the supported values in the server configuration document using the new standardprompt_values_supported
node. See #2197 for more information.
Note
As part of this change, the OpenIddictConstants.Prompts
class was renamed to OpenIddictConstants.PromptValues
to match the name used in this specification.
5.8.0
This release introduces the following changes:
-
The OpenIddict client system integration now natively supports Android API 21+ (Android 5.0 and higher), iOS 12.0+, macOS 10.15+ and Mac Catalyst 13.1+. See Operating systems integration for more information.
-
Behavior change: the
OpenIddict.Client.SystemIntegration
package was updated to produce shorter default pipe names (which is required on macOS where strict length restrictions are enforced). -
The
OpenIddict.Client.SystemNetHttp
andOpenIddict.Validation.SystemNetHttp
packages have been updated to anticipate a breaking change introduced in the 9.0 version ofMicrosoft.Extensions.Http
. See dotnet/runtime#35987 (comment) for more information. -
6 new web providers were added to
OpenIddict.Client.WebIntegration
:- Airtable
- Calendly
- Pipedrive
- Typeform
- Twitch (thanks @mbaumanndev! ❤️)
- Zoho
-
OpenIddict now uses
Microsoft.IdentityModel
8.x on .NET 8.0 and higher. -
The
OpenIddict.EntityFramework
package now usesEntityFramework
6.5.1 as the minimum version.
5.7.1
This release introduces the following changes:
- The LinkedIn integration was updated to react to a breaking change introduced by LinkedIn in their discovery document and that was causing an issuer validation error in the OpenIddict client due to the issuer being changed from
https://www.linkedin.com/
tohttps://www.linkedin.com/oauth
(thanks @DovydasNavickas! ❤️).
Important
If your code relies on the issuer identity, make sure you update your code/database to use https://www.linkedin.com/oauth
instead of https://www.linkedin.com/
.
5.7.0
This release introduces the following changes:
-
To increase interoperability and support advanced scenarios, the OpenIddict server now allows using OAuth 2.0 Proof Key for Code Exchange with
response_type
combinations containingtoken
when response type permissions are not disabled and the appropriate response type permissions are granted to the client application. See #2088 for more information about this change. -
The embedded web server that is part of the OpenIddict client system integration package now natively supports POST callbacks, allowing to use the implicit and hybrid flows - that require
response_mode=form_post
- in desktop applications. -
response_mode=fragment
is now fully supported by the system integration package when using protocol activations or the UWP web authentication broker. -
The OpenIddict client and its ASP.NET Core/OWIN integrations now support setting a specific
code_challenge_method
/grant_type
/response_mode
/response_type
for each challenge operation:
// Ask OpenIddict to initiate the authentication flow (typically, by starting the system browser).
var result = await _service.ChallengeInteractivelyAsync(new()
{
// Note: both the grant type and the response type MUST be set when using a specific flow:
GrantType = GrantTypes.AuthorizationCode,
ResponseType = ResponseTypes.Code + ' ' + ResponseTypes.IdToken
});
var properties = new AuthenticationProperties(new Dictionary<string, string>
{
// Note: both the grant type and the response type MUST be set when using a specific flow:
[OpenIddictClientAspNetCoreConstants.Properties.GrantType] = GrantTypes.AuthorizationCode,
[OpenIddictClientAspNetCoreConstants.Properties.ResponseType] = ResponseTypes.Code + ' ' + ResponseTypes.IdToken
})
{
RedirectUri = Url.IsLocalUrl(returnUrl) ? returnUrl : "/"
};
return Challenge(properties, OpenIddictClientAspNetCoreDefaults.AuthenticationScheme);
-
The following providers are now supported by the
OpenIddict.Client.WebIntegration
package:- Gitee (thanks @gehongyan! ❤️)
- Huawei (thanks @gehongyan! ❤️)
- KOOK (thanks @gehongyan! ❤️)
- Lark/Feishu (thanks @gehongyan! ❤️)
- Weibo (thanks @gehongyan! ❤️)
-
Behavior change: for boolean values,
OpenIddictParameter.ToString()
and thestring?
/string?[]?
conversion operators now returntrue
andfalse
instead ofTrue
andFalse
. -
The OpenIddict client was updated to detect incorrect uses of its system integration package in non-desktop applications and return proper errors.
5.6.0
This release introduces the following changes:
-
The core, client, server and validation stacks now use
System.TimeProvider
on .NET 8.0+ (thanks @trejjam! ❤️). -
While manually setting
OpenIddictClientRegistration.CodeChallengeMethods
,OpenIddictClientRegistration.GrantTypes
,OpenIddictClientRegistration.ResponseModes
orOpenIddictClientRegistration.ResponseTypes
is not necessary or recommended in most cases (as OpenIddict automatically negotiates the best values automatically), specific scenarios sometimes require restricting the allowed values. To make that easier, new (advanced) APIs were added to the web provider builders:
options.UseWebProviders()
.AddMicrosoft(options =>
{
// ...
options.AddCodeChallengeMethods(CodeChallengeMethods.Sha256)
.AddGrantTypes(GrantTypes.AuthorizationCode, GrantTypes.Implicit)
.AddResponseModes(ResponseModes.FormPost)
.AddResponseTypes(ResponseTypes.Code + ' ' + ResponseTypes.IdToken);
});
- The OpenIddict validation ASP.NET Core and OWIN hosts now allow tweaking how access tokens are extracted:
options.UseAspNetCore()
.DisableAccessTokenExtractionFromAuthorizationHeader()
.DisableAccessTokenExtractionFromBodyForm()
.DisableAccessTokenExtractionFromQueryString();
options.UseOwin()
.DisableAccessTokenExtractionFromAuthorizationHeader()
.DisableAccessTokenExtractionFromBodyForm()
.DisableAccessTokenExtractionFromQueryString();
-
Behavior change: the claim value type validation logic was fixed to support
JSON_ARRAY
claims. As part of this change, theClaimsIdentity.GetClaims()
/ClaimsPrincipal.GetClaims()
extensions have been updated to supportJSON_ARRAY
claims and return all the values contained in the array. -
A bug preventing the OpenIddict client from using the OpenID Connect implicit flow was fixed.
-
The Clever provider was updated to not require a backchannel identity token (thanks @anarian! ❤️).
-
The Auth0 and Microsoft Account/Entra ID providers were fixed to list
implicit
as a supported grant type.
5.5.0
This release introduces the following changes:
- Similarly to what was already possible with the OpenIddict client system integration, the ASP.NET Core (and OWIN) hosts now allow overriding the requested scopes dynamically/per challenge. For that, an
OpenIddictClientAspNetCoreConstants.Properties.Scope
property must be added to theAuthenticationProperties.Items
collection with the space-separated list of scopes that should be attached to the authorization request:
var properties = new AuthenticationProperties();
// Override the scopes configured globally for this challenge operation.
properties.SetString(OpenIddictClientAspNetCoreConstants.Properties.Scope, "api_1_scope api_2_scope");
return Challenge(properties, Providers.GitHub);
- FACEIT is now supported by
OpenIddict.Client.WebIntegration
.
5.4.0
This release introduces the following changes:
- The client stack now allows configuring and using custom grant types for advanced scenarios:
options.AllowCustomFlow("my-custom-grant-type");
var result = await _service.AuthenticateWithCustomGrantAsync(new()
{
AdditionalTokenRequestParameters = new()
{
["my-custom-parameter"] = "value"
},
CancellationToken = stoppingToken,
GrantType = "my-custom-grant-type",
ProviderName = provider,
Scopes = [Scopes.OfflineAccess]
});
Note
When using a custom grant type, the following logic is enforced by default:
- A token request is always sent.
- An access token MUST be returned by the authorization server as part of the token response.
- An identity token MAY be returned by the authorization server as part of the token response but it's not mandatory (in this case, OpenIddict will resolve it and extract the principal it contains, but won't reject the response if it's invalid).
- A refresh token MAY be returned by the authorization server as part of the token response but it's not mandatory.
- A userinfo request is always sent when an access token was returned and a userinfo endpoint is available, unless userinfo retrieval was explicitly disabled when calling
AuthenticateWithCustomGrantAsync()
.
- The length of user codes - used in the OAuth 2.0 device authorization flow - can now be configured in the server options:
options.SetUserCodeLength(7);
Important
For security reasons, OpenIddict will throw an ArgumentOutOfRangeException
if you try to configure a length that is less than 6 characters.
- The charset used by OpenIddict to create random user codes can now be configured in the server options:
options.SetUserCodeCharset(
[
"B", "C", "D", "F", "G", "H", "J", "K", "L", "M",
"N", "P", "Q", "R", "S", "T", "V", "W", "X", "Z"
]);
Tip
All characters are allowed - including emojis - as long as they represent exactly one extended grapheme cluster (note: non-ASCII characters are only supported on .NET 6.0 and higher).
Important
For security reasons, OpenIddict will throw an ArgumentOutOfRangeException
if you try to configure a charset that includes less than 9 characters.
- The display format used by OpenIddict to "beautify" the user codes can now be controlled using a new
options.SetUserCodeDisplayFormat()
API:
options.SetUserCodeDisplayFormat("{0}{1} - {2}{3}{4} - {5}{6}");
Tip
If no value is explicitly set, OpenIddict will use the same format as in previous versions (i.e multiple groups of characters separated by dashes).
-
User codes are now re-formatted automatically: developers who want to display them (e.g for a confirmation form) are invited to retrieve them using
result.Properties.GetTokenValue(OpenIddictServerAspNetCoreConstants.Tokens.UserCode)
- so that a properly formatted code is displayed - instead of usingOpenIddictRequest.UserCode
. -
The following providers are now supported by
OpenIddict.Client.WebIntegration
:
5.3.0
This release introduces the following changes:
- Native support for interactive sign-out was added to the
OpenIddict.Client.SystemIntegration
package. To support this new feature, a newSignOutInteractivelyAsync()
API (similar to the existingChallengeInteractivelyAsync()
API used to start a new authentication flow) has been added toOpenIddictClientService
:
// Ask OpenIddict to initiate the logout flow (typically, by starting the system browser).
var result = await _service.SignOutInteractivelyAsync(new()
{
CancellationToken = stoppingToken,
ProviderName = provider
});
- The client stack now natively supports OAuth 2.0 introspection, which allows querying the authorization server to determine the set of metadata for a given token - typically an access or refresh token - and, depending on the server policy, retrieve its actual content:
var result = await _service.IntrospectTokenAsync(new()
{
CancellationToken = stoppingToken,
ProviderName = provider,
Token = response.BackchannelAccessToken,
TokenTypeHint = TokenTypeHints.AccessToken
});
Important
As part of this change, the introspection implementation of the validation stack was reworked to be consistent with its new client counterpart. Most notably, the ValidateToken
event is no longer invoked for introspected tokens (a change that had been introduced in OpenIddict 5.0): developers who want to apply custom logic to introspected tokens/principals are invited to use the ProcessAuthentication
event instead.
- Support for OAuth 2.0 revocation was also added to the client stack to allow revoking an access or refresh token (and, depending on the server policy, the associated authorization grant):
var result = await _service.RevokeTokenAsync(new()
{
CancellationToken = stoppingToken,
ProviderName = provider,
Token = response.BackchannelAccessToken,
TokenTypeHint = TokenTypeHints.AccessToken
});
Note
The Apple, DeviantArt, Discord, Reddit, Trakt and Zoom web providers have been updated to support token revocation.
- On .NET 8.0 and higher, the
OpenIddict.Client.SystemNetHttp
andOpenIddict.Validation.SystemNetHttp
packages now natively supportMicrosoft.Extensions.Http.Resilience
and use aResiliencePipeline<HttpResponseMessage>
by default (unless anIAsyncPolicy<HttpResponseMessage>
was explicitly configured by the user).
Tip
If necessary, the default resilience pipeline can be easily overridden using the SetHttpResiliencePipeline()
API:
options.UseSystemNetHttp(options => options.SetHttpResiliencePipeline(options =>
{
options.AddRetry(new HttpRetryStrategyOptions
{
BackoffType = DelayBackoffType.Exponential,
Delay = TimeSpan.FromSeconds(1),
MaxRetryAttempts = 2
});
options.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
BreakDuration = TimeSpan.FromSeconds(10),
FailureRatio = 0.9,
MinimumThroughput = 5,
SamplingDuration = TimeSpan.FromSeconds(5)
});
}));
-
10 new web providers have been added to the
OpenIddict.Client.WebIntegration
package:- Bitly
- Box
- Dailymotion
- Disqus
- DocuSign
- Mastodon
- Meetup
- MusicBrainz
- OpenStreetMap
- Tidal
-
The Spotify provider was updated to use PKCE (OAuth 2.0 Proof Key for Code Exchange).
-
UWP support in
OpenIddict.Client.SystemIntegration
is now provided via a dedicateduap10.0.17763
TFM.
Important
As part of this change, the netstandard2.0
and netstandard2.1
versions of OpenIddict.Client.SystemIntegration
have been updated to stop using the Windows Runtime APIs (internally used to launch the system browser, integrate with the web authentication broker or handle protocol activations).
The net461
, net472
, net48
, net6.0-windows10.0.17763
, net7.0-windows10.0.17763
or net8.0-windows10.0.17763
versions of OpenIddict.Client.SystemIntegration
still use these APIs internally - with runtime checks in place to ensure older platforms are still supported - so non-UWP Windows applications should behave the same way as in previous versions.