Flexible and versatile OAuth 2.0/OpenID Connect stack for .NET
This release introduces the following changes:
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);
OpenIddict.Client.WebIntegration
.This release introduces the following changes:
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()
.
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.
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.
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
:
This release introduces the following changes:
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
});
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 theProcessAuthentication
event instead.
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.
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:
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
andnetstandard2.1
versions ofOpenIddict.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
ornet8.0-windows10.0.17763
versions ofOpenIddict.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.
This release introduces the following changes:
The client stack now maps ClaimTypes.Name
from the standard OpenID Connect name
claim when no preferred_username
is present.
A merged principal containing the claims extracted from the userinfo response and the identity token (if available) is now automatically created by OpenIddict during the refresh token flow processing and exposed via RefreshTokenAuthenticationResult.Principal
.
Amazon and Exact Online are now supported by OpenIddict.Client.WebIntegration
.
A bug that prevented attaching a specific token lifetime when using ASP.NET Core Data Protection tokens was identified and fixed (thanks @schneini for reporting it!)
The EF 6 and EF Core stores have been optimized to avoid sending unnecessary database queries when creating new authorization and token entries (thanks @Elfster for the suggestion!). The OpenIddictEntityFramework(Core)*Store.FindBy*Async()
methods that return a single result have also been updated to try to resolve the entity from the change tracker before sending a query.
This release introduces the following changes:
Behavior change: the ClaimsIdentity.GetClaim()
/ClaimsPrincipal.GetClaim()
extension now throws an InvalidOperationException
when multiple claims of the same type were found in the identity/principal (instead of returning the first value and ignoring the other ones as in previous versions). See https://github.com/openiddict/openiddict-core/pull/1957 for more information.
Behavior change: the server stack now automatically aborts sign-in operations that specify a ClaimsPrincipal
containing a well-known claim with an invalid cardinality or an incorrect value type attached (e.g multiple sub
claims or a sub
claim created with ClaimValueTypes.Integer
instead of ClaimValueTypes.String
). See https://github.com/openiddict/openiddict-core/issues/1956 for more information.
Client assertions that don't specify an optional iat
claim are no longer rejected by the server stack.
A new OpenIddictClientService.GetClientRegistrationsAsync()
API was introduced to allow resolving the client registrations in a dynamic way, which can be used in non-ASP.NET Core/OWIN applications (e.g console or desktop applications) to easily list the supported web providers:
var provider = AnsiConsole.Prompt(new SelectionPrompt<OpenIddictClientRegistration>()
.Title("Select the authentication provider you'd like to log in with.")
.AddChoices(from registration in await _service.GetClientRegistrationsAsync(stoppingToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration)
.UseConverter(registration => registration.ProviderDisplayName!)).ProviderName!;
A new DisableUserinfo
property was added to RefreshTokenAuthenticationRequest
to allow disabling userinfo for specific refresh token requests (e.g when using refresh tokens with the client credentials grant).
The client and server stacks have been updated to automatically restore the authentication properties initially set by the application (via ProcessChallengeContext.Properties
or ProcessSignOutContext.Properties
) and attach them to the authentication context (ProcessAuthenticationContext.Properties
). This scenario was already supported by the ASP.NET Core and OWIN hosts, but is now supported for all integrations, including OpenIddict.Client.SystemIntegration
and OpenIddict.Client.WebIntegration
:
// Ask OpenIddict to initiate the authentication flow (typically, by starting the system browser).
var result = await _service.ChallengeInteractivelyAsync(new()
{
CancellationToken = stoppingToken,
ProviderName = provider,
Properties = new()
{
["custom_property"] = "value"
}
});
// Wait for the user to complete the authorization process.
var response = await _service.AuthenticateInteractivelyAsync(new()
{
CancellationToken = stoppingToken,
Nonce = result.Nonce
});
var property = response.Properties["custom_property"];
The following providers have been added to the OpenIddict.Client.WebIntegration
package:
The Twitter integration now automatically maps the name
userinfo claim to its ClaimTypes.Name
equivalent.
The Microsoft.IdentityModel.*
packages have been updated to 7.2.0 to address a security issue. See https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/security/advisories/GHSA-8g9c-28fc-mcx2 for more information.
References to Azure Active Directory in the code documentation have been replaced by "Microsoft Entra ID" to match the new name of the service (see https://techcommunity.microsoft.com/t5/microsoft-entra-azure-ad-blog/azure-ad-is-becoming-microsoft-entra-id/ba-p/2520436 for more information).
This release introduces the following changes:
For more information about this release, read OpenIddict 5.0 general availability.
This release introduces the following changes:
TokenValidationParameters.ClockSkew
is now supported by OpenIddict, that will honor it when validating the expiration date of a token.
A bug preventing the OpenIddictClientService.ChallengeUsingDeviceAsync()
and OpenIddictClientService.AuthenticateWithDeviceAsync()
APIs from flowing the additional device authorization request/token request parameters set by the application was identified and fixed (thanks @hangy for reporting it! ❤️)
A bug preventing signing/encryption certificates from being correctly sorted was identified and fixed (thanks Stefan Chiriac for reporting the issue and suggesting the fix!)
Note: 5.0.0-rc1 is the last preview before RTM ships next week. As such, OpenIddict users are invited to start testing 5.0.0-rc1 and share their feedback to ensure no regression affects their applications.
This release introduces the following changes:
OpenIddictClientService.ChallengeUsingDeviceAsync()
and OpenIddictClientService.AuthenticateWithDeviceAsync()
APIs from flowing the additional device authorization request/token request parameters set by the application was identified and fixed (thanks @hangy for reporting it! ❤️)This release introduces the following changes:
On .NET 7.0 and higher, the Entity Framework Core stores now use bulk updates and bulk deletes when large amounts of entities are expected to be updated/removed. If necessary, bulk operations can be disabled by calling options.DisableBulkOperations()
in the OpenIddict EF Core stores options.
A new IOpenIddictTokenManager.RevokeByAuthorizationIdAsync()
API was introduced to dramatically improve the performance of token revocation when using the Entity Framework Core (.NET 7.0+-only) or MongoDB stores.
The Entity Framework Core stores that use IDbTransaction
were updated to run these operations inside execution strategies, which allows using the built-in stores with options.EnableRetryOnFailure()
without having to override them.
The IOpenIddictAuthorizationManager.PruneAsync()
and IOpenIddictTokenManager.PruneAsync()
APIs (and the corresponding stores methods) now return the number of authorizations/tokens that were removed.
Constants for the standard claim request members were added (thanks @davhdavh! ❤️)
Note: 5.0.0-preview3
is likely one of the very last previews before RTM ships later this month. As such, OpenIddict users will be invited to start testing 5.0.0-preview3
and share their feedback during the next few weeks.