Skip to content

Releases: openiddict/openiddict-core

6.0.0-preview3

01 Nov 10:01
Compare
Choose a tag to compare
6.0.0-preview3 Pre-release
Pre-release

This release introduces the following changes:

  • The existing IOpenIddictAuthorizationManager.FindAsync(...) and IOpenIddictTokenManager.FindAsync(...) overloads have been merged and replaced by a single method where all the parameters are now optional (for instance, if a null subject value is specified when calling IOpenIddictAuthorizationManager.FindAsync(...), the returned collection will contain authorizations for all users).

  • New IOpenIddictAuthorizationManager.RevokeAsync(...) and IOpenIddictTokenManager.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

22 Oct 14:16
Compare
Choose a tag to compare
6.0.0-preview2 Pre-release
Pre-release

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 and OpenIddict.MongoDb.Models packages now reference MongoDB.Driver and MongoDB.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 and Claim.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 the Claim.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, the GetPrompts() and HasPrompt() extension have been renamed to GetPromptValues() and HasPromptValue().

6.0.0-preview1

04 Oct 19:16
Compare
Choose a tag to compare
6.0.0-preview1 Pre-release
Pre-release

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 or self_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 existing RevokeByAuthorizationIdAsync() 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 standard prompt_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

22 Aug 09:13
Compare
Choose a tag to compare

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 and OpenIddict.Validation.SystemNetHttp packages have been updated to anticipate a breaking change introduced in the 9.0 version of Microsoft.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 uses EntityFramework 6.5.1 as the minimum version.

5.7.1

15 Aug 19:06
Compare
Choose a tag to compare

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/ to https://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

19 Jun 18:23
Compare
Choose a tag to compare

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 containing token 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:

  • Behavior change: for boolean values, OpenIddictParameter.ToString() and the string?/string?[]? conversion operators now return true and false instead of True and False.

  • 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

14 May 14:37
Compare
Choose a tag to compare

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 or OpenIddictClientRegistration.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, the ClaimsIdentity.GetClaims()/ClaimsPrincipal.GetClaims() extensions have been updated to support JSON_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

25 Apr 16:17
Compare
Choose a tag to compare

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 the AuthenticationProperties.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

26 Mar 16:55
Compare
Choose a tag to compare

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 using OpenIddictRequest.UserCode.

  • The following providers are now supported by OpenIddict.Client.WebIntegration:

    • Atlassian
    • ClassLink (thanks @anarian! ❤️)
    • Clever (thanks @anarian! ❤️)
    • Todoist
    • Wikimedia

5.3.0

04 Mar 16:21
Compare
Choose a tag to compare

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 new SignOutInteractivelyAsync() API (similar to the existing ChallengeInteractivelyAsync() API used to start a new authentication flow) has been added to OpenIddictClientService:
// 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 and OpenIddict.Validation.SystemNetHttp packages now natively support Microsoft.Extensions.Http.Resilience and use a ResiliencePipeline<HttpResponseMessage> by default (unless an IAsyncPolicy<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 dedicated uap10.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.