diff --git a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
index f22b2404..24a39582 100644
--- a/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
+++ b/src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
@@ -1776,10 +1776,6 @@ To register the OpenIddict core services, reference the 'OpenIddict.Core' packag
The token shouldn't be null or empty at this point.
{Locked}
-
- The OpenIddict Core services should be registered.
- {Locked}
-
An error occurred while validating the token '{Token}'.
{Locked}
diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
index 98d78bfd..e9e03cdb 100644
--- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
+++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.Session.cs
@@ -244,13 +244,13 @@ namespace OpenIddict.Server.AspNetCore
encryptingCredentials: context.Options.EncryptionCredentials.First(),
additionalHeaderClaims: new Dictionary
{
- [JwtHeaderParameterNames.Typ] = JsonWebTokenTypes.Private.AuthorizationRequest
+ [JwtHeaderParameterNames.Typ] = JsonWebTokenTypes.Private.LogoutRequest
});
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetStringAsync(Cache.LogoutRequest + context.Request.RequestId,
- token, _options.CurrentValue.AuthorizationEndpointCachingPolicy);
+ token, _options.CurrentValue.LogoutEndpointCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = QueryHelpers.AddQueryString(
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
index 1e057f49..79fca055 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
@@ -177,7 +177,7 @@ namespace OpenIddict.Server.DataProtection
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelAccessToken.Descriptor.Order - 500)
@@ -240,7 +240,7 @@ namespace OpenIddict.Server.DataProtection
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelAuthorizationCode.Descriptor.Order - 500)
@@ -303,7 +303,7 @@ namespace OpenIddict.Server.DataProtection
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelDeviceCode.Descriptor.Order - 500)
@@ -366,7 +366,7 @@ namespace OpenIddict.Server.DataProtection
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelRefreshToken.Descriptor.Order - 500)
@@ -429,7 +429,7 @@ namespace OpenIddict.Server.DataProtection
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelUserCode.Descriptor.Order - 500)
diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
index ce199ebe..c60f799e 100644
--- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
+++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.Session.cs
@@ -244,7 +244,7 @@ namespace OpenIddict.Server.Owin
// Note: the cache key is always prefixed with a specific marker
// to avoid collisions with the other types of cached payloads.
await _cache.SetStringAsync(Cache.LogoutRequest + context.Request.RequestId,
- token, _options.CurrentValue.AuthorizationEndpointCachingPolicy);
+ token, _options.CurrentValue.LogoutEndpointCachingPolicy);
// Create a new GET logout request containing only the request_id parameter.
var address = WebUtilities.AddQueryString(
diff --git a/src/OpenIddict.Server/OpenIddictServerEvents.cs b/src/OpenIddict.Server/OpenIddictServerEvents.cs
index fad33170..64f7d4f7 100644
--- a/src/OpenIddict.Server/OpenIddictServerEvents.cs
+++ b/src/OpenIddict.Server/OpenIddictServerEvents.cs
@@ -387,82 +387,172 @@ namespace OpenIddict.Server
///
/// Gets or sets a boolean indicating whether an access token
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
- public bool IncludeAccessToken { get; set; }
+ public bool GenerateAccessToken { get; set; }
///
/// Gets or sets a boolean indicating whether an authorization code
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
- public bool IncludeAuthorizationCode { get; set; }
+ public bool GenerateAuthorizationCode { get; set; }
///
/// Gets or sets a boolean indicating whether a device code
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
- public bool IncludeDeviceCode { get; set; }
+ public bool GenerateDeviceCode { get; set; }
///
/// Gets or sets a boolean indicating whether an identity token
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
- public bool IncludeIdentityToken { get; set; }
+ public bool GenerateIdentityToken { get; set; }
///
/// Gets or sets a boolean indicating whether a refresh token
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
- public bool IncludeRefreshToken { get; set; }
+ public bool GenerateRefreshToken { get; set; }
///
/// Gets or sets a boolean indicating whether a user code
- /// should be returned to the client application.
+ /// should be generated (and optionally returned to the client).
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool GenerateUserCode { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated access token
+ /// should be returned to the client application as part of the response.
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool IncludeAccessToken { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated authorization code
+ /// should be returned to the client application as part of the response.
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool IncludeAuthorizationCode { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated device code
+ /// should be returned to the client application as part of the response.
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool IncludeDeviceCode { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated identity token
+ /// should be returned to the client application as part of the response.
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool IncludeIdentityToken { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated refresh token
+ /// should be returned to the client application as part of the response.
+ /// Note: overriding the value of this property is generally not
+ /// recommended, except when dealing with non-standard clients.
+ ///
+ public bool IncludeRefreshToken { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the generated user code
+ /// should be returned to the client application as part of the response.
/// Note: overriding the value of this property is generally not
/// recommended, except when dealing with non-standard clients.
///
public bool IncludeUserCode { get; set; }
+ ///
+ /// Gets or sets the generated access token, if applicable.
+ /// The access token will only be returned if
+ /// is set to true.
+ ///
+ public string? AccessToken { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the access token, if applicable.
///
public ClaimsPrincipal? AccessTokenPrincipal { get; set; }
+ ///
+ /// Gets or sets the generated authorization code, if applicable.
+ /// The authorization code will only be returned if
+ /// is set to true.
+ ///
+ public string? AuthorizationCode { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the authorization code, if applicable.
///
public ClaimsPrincipal? AuthorizationCodePrincipal { get; set; }
+ ///
+ /// Gets or sets the generated device code, if applicable.
+ /// The device code will only be returned if
+ /// is set to true.
+ ///
+ public string? DeviceCode { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the device code, if applicable.
///
public ClaimsPrincipal? DeviceCodePrincipal { get; set; }
+ ///
+ /// Gets or sets the generated identity token, if applicable.
+ /// The identity token will only be returned if
+ /// is set to true.
+ ///
+ public string? IdentityToken { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the identity token, if applicable.
///
public ClaimsPrincipal? IdentityTokenPrincipal { get; set; }
+ ///
+ /// Gets or sets the generated refresh token, if applicable.
+ /// The refresh token will only be returned if
+ /// is set to true.
+ ///
+ public string? RefreshToken { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the refresh token, if applicable.
///
public ClaimsPrincipal? RefreshTokenPrincipal { get; set; }
+ ///
+ /// Gets or sets the generated user code, if applicable.
+ /// The user code will only be returned if
+ /// is set to true.
+ ///
+ public string? UserCode { get; set; }
+
///
/// Gets or sets the principal containing the claims that
/// will be used to create the user code, if applicable.
diff --git a/src/OpenIddict.Server/OpenIddictServerExtensions.cs b/src/OpenIddict.Server/OpenIddictServerExtensions.cs
index 6ae522c6..2c40955b 100644
--- a/src/OpenIddict.Server/OpenIddictServerExtensions.cs
+++ b/src/OpenIddict.Server/OpenIddictServerExtensions.cs
@@ -48,25 +48,25 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filters used by the default OpenIddict server event handlers.
- builder.Services.TryAddSingleton();
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
@@ -75,7 +75,7 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs b/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
index caffae2a..0600c68a 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
@@ -15,9 +15,9 @@ namespace OpenIddict.Server
public static class OpenIddictServerHandlerFilters
{
///
- /// Represents a filter that excludes the associated handlers if no access token is returned.
+ /// Represents a filter that excludes the associated handlers if no access token is generated.
///
- public class RequireAccessTokenIncluded : IOpenIddictServerHandlerFilter
+ public class RequireAccessTokenGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -26,14 +26,14 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeAccessToken);
+ return new ValueTask(context.GenerateAccessToken);
}
}
///
- /// Represents a filter that excludes the associated handlers if no authorization code is returned.
+ /// Represents a filter that excludes the associated handlers if no authorization code is generated.
///
- public class RequireAuthorizationCodeIncluded : IOpenIddictServerHandlerFilter
+ public class RequireAuthorizationCodeGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -42,7 +42,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeAuthorizationCode);
+ return new ValueTask(context.GenerateAuthorizationCode);
}
}
@@ -143,9 +143,9 @@ namespace OpenIddict.Server
}
///
- /// Represents a filter that excludes the associated handlers if no device code is returned.
+ /// Represents a filter that excludes the associated handlers if no device code is generated.
///
- public class RequireDeviceCodeIncluded : IOpenIddictServerHandlerFilter
+ public class RequireDeviceCodeGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -154,7 +154,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeDeviceCode);
+ return new ValueTask(context.GenerateDeviceCode);
}
}
@@ -207,9 +207,9 @@ namespace OpenIddict.Server
}
///
- /// Represents a filter that excludes the associated handlers if no identity token is returned.
+ /// Represents a filter that excludes the associated handlers if no identity token is generated.
///
- public class RequireIdentityTokenIncluded : IOpenIddictServerHandlerFilter
+ public class RequireIdentityTokenGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -218,7 +218,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeIdentityToken);
+ return new ValueTask(context.GenerateIdentityToken);
}
}
@@ -303,9 +303,9 @@ namespace OpenIddict.Server
}
///
- /// Represents a filter that excludes the associated handlers if no refresh token is returned.
+ /// Represents a filter that excludes the associated handlers if no refresh token is generated.
///
- public class RequireRefreshTokenIncluded : IOpenIddictServerHandlerFilter
+ public class RequireRefreshTokenGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -314,7 +314,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeRefreshToken);
+ return new ValueTask(context.GenerateRefreshToken);
}
}
@@ -447,9 +447,9 @@ namespace OpenIddict.Server
}
///
- /// Represents a filter that excludes the associated handlers if no user code is returned.
+ /// Represents a filter that excludes the associated handlers if no user code is generated.
///
- public class RequireUserCodeIncluded : IOpenIddictServerHandlerFilter
+ public class RequireUserCodeGenerated : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync(ProcessSignInContext context)
{
@@ -458,7 +458,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.IncludeUserCode);
+ return new ValueTask(context.GenerateUserCode);
}
}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
index 6b22bbc0..e0607006 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs
@@ -1121,7 +1121,10 @@ namespace OpenIddict.Server
// even if the service was registered and resolved from the dependency injection container.
if (scopes.Count != 0 && !context.Options.EnableDegradedMode)
{
- Debug.Assert(_scopeManager is not null, SR.GetResourceString(SR.ID4011));
+ if (_scopeManager is null)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
+ }
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
index a3cbb1da..3bd8e9c2 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs
@@ -405,7 +405,10 @@ namespace OpenIddict.Server
// even if the service was registered and resolved from the dependency injection container.
if (scopes.Count != 0 && !context.Options.EnableDegradedMode)
{
- Debug.Assert(_scopeManager is not null, SR.GetResourceString(SR.ID4011));
+ if (_scopeManager is null)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
+ }
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
index ee2a8160..757722f0 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs
@@ -686,7 +686,10 @@ namespace OpenIddict.Server
// even if the service was registered and resolved from the dependency injection container.
if (scopes.Count != 0 && !context.Options.EnableDegradedMode)
{
- Debug.Assert(_scopeManager is not null, SR.GetResourceString(SR.ID4011));
+ if (_scopeManager is null)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(SR.ID0016));
+ }
await foreach (var scope in _scopeManager.FindByNamesAsync(scopes.ToImmutableArray()))
{
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
index 253d384c..27efd548 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
@@ -63,7 +63,7 @@ namespace OpenIddict.Server
AttachDefaultScopes.Descriptor,
AttachDefaultPresenters.Descriptor,
InferResources.Descriptor,
- EvaluateReturnedTokens.Descriptor,
+ EvaluateTokenTypes.Descriptor,
AttachAuthorization.Descriptor,
PrepareAccessTokenPrincipal.Descriptor,
@@ -104,8 +104,7 @@ namespace OpenIddict.Server
GenerateIdentityModelIdentityToken.Descriptor,
BeautifyUserCode.Descriptor,
- AttachAccessTokenProperties.Descriptor,
- AttachDeviceCodeProperties.Descriptor,
+ AttachTokenParameters.Descriptor,
/*
* Sign-out processing:
@@ -1575,16 +1574,17 @@ namespace OpenIddict.Server
}
///
- /// Contains the logic responsible of selecting the token types returned to the client application.
+ /// Contains the logic responsible of selecting the token types that
+ /// should be generated and optionally returned in the response.
///
- public class EvaluateReturnedTokens : IOpenIddictServerHandler
+ public class EvaluateTokenTypes : IOpenIddictServerHandler
{
///
/// Gets the default descriptor definition assigned to this handler.
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .UseSingletonHandler()
+ .UseSingletonHandler()
.SetOrder(InferResources.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
@@ -1599,73 +1599,80 @@ namespace OpenIddict.Server
Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
- context.IncludeAccessToken = context.EndpointType switch
+ (context.GenerateAccessToken, context.IncludeAccessToken) = context.EndpointType switch
{
- // For authorization requests, return an access token if a response type containing token was specified.
- OpenIddictServerEndpointType.Authorization => context.Request.HasResponseType(ResponseTypes.Token),
+ // For authorization requests, generate and return an access token
+ // if a response type containing the "token" value was specified.
+ OpenIddictServerEndpointType.Authorization when context.Request.HasResponseType(ResponseTypes.Token)
+ => (true, true),
- // For token requests, always return an access token.
- OpenIddictServerEndpointType.Token => true,
+ // For token requests, always generate and return an access token.
+ OpenIddictServerEndpointType.Token => (true, true),
- _ => false
+ _ => (false, false)
};
- context.IncludeAuthorizationCode = context.EndpointType switch
+ (context.GenerateAuthorizationCode, context.IncludeAuthorizationCode) = context.EndpointType switch
{
- // For authorization requests, return an authorization code if a response type containing code was specified.
- OpenIddictServerEndpointType.Authorization => context.Request.HasResponseType(ResponseTypes.Code),
+ // For authorization requests, generate and return an authorization code
+ // if a response type containing the "code" value was specified.
+ OpenIddictServerEndpointType.Authorization when context.Request.HasResponseType(ResponseTypes.Code)
+ => (true, true),
- _ => false
+ _ => (false, false)
};
- context.IncludeDeviceCode = context.EndpointType switch
+ (context.GenerateDeviceCode, context.IncludeDeviceCode) = context.EndpointType switch
{
- // For device requests, always return a device code.
- OpenIddictServerEndpointType.Device => true,
+ // For device requests, always generate and return a device code.
+ OpenIddictServerEndpointType.Device => (true, true),
// Note: a device code is not directly returned by the verification endpoint (that generally
// returns an empty response or redirects the user agent to another page), but a device code
// must be generated to replace the payload of the device code initially returned to the client.
- // In this case, the new device code is not returned as part of the response but persisted in the DB.
- OpenIddictServerEndpointType.Verification => true,
+ // In this case, the device code is not returned as part of the response but persisted in the DB.
+ OpenIddictServerEndpointType.Verification => (true, false),
- _ => false
+ _ => (false, false)
};
- context.IncludeRefreshToken = context.EndpointType switch
+ (context.GenerateIdentityToken, context.IncludeIdentityToken) = context.EndpointType switch
{
- // For token requests, never return a refresh token if the offline_access scope was not granted.
- OpenIddictServerEndpointType.Token when !context.Principal.HasScope(Scopes.OfflineAccess) => false,
+ // For authorization requests, generate and return an identity token if a response type
+ // containing code was specified and if the openid scope was explicitly or implicitly granted.
+ OpenIddictServerEndpointType.Authorization when
+ context.Principal.HasScope(Scopes.OpenId) &&
+ context.Request.HasResponseType(ResponseTypes.IdToken) => (true, true),
- // For grant_type=refresh_token token requests, only return a refresh token if rolling tokens are enabled.
- OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType()
- => context.Options.UseRollingRefreshTokens,
-
- // For token requests that don't meet the previous criteria, allow a refresh token to be returned.
- OpenIddictServerEndpointType.Token => true,
+ // For token requests, only generate and return an identity token if the openid scope was granted.
+ OpenIddictServerEndpointType.Token when context.Principal.HasScope(Scopes.OpenId) => (true, true),
- _ => false
+ _ => (false, false)
};
- context.IncludeIdentityToken = context.EndpointType switch
+ (context.GenerateRefreshToken, context.IncludeRefreshToken) = context.EndpointType switch
{
- // For authorization requests, return an identity token if a response type containing code
- // was specified and if the openid scope was explicitly or implicitly granted.
- OpenIddictServerEndpointType.Authorization => context.Principal.HasScope(Scopes.OpenId) &&
- context.Request.HasResponseType(ResponseTypes.IdToken),
+ // For token requests, never generate a refresh token if the offline_access scope was not granted.
+ OpenIddictServerEndpointType.Token when !context.Principal.HasScope(Scopes.OfflineAccess)
+ => (false, false),
- // For token requests, only return an identity token if the openid scope was granted.
- OpenIddictServerEndpointType.Token => context.Principal.HasScope(Scopes.OpenId),
+ // For grant_type=refresh_token token requests, only generate
+ // and return a refresh token if rolling tokens are enabled.
+ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType() &&
+ context.Options.UseRollingRefreshTokens => (true, true),
- _ => false
+ // For token requests that don't meet the previous criteria, allow a refresh token to be returned.
+ OpenIddictServerEndpointType.Token when !context.Request.IsRefreshTokenGrantType() => (true, true),
+
+ _ => (false, false)
};
- context.IncludeUserCode = context.EndpointType switch
+ (context.GenerateUserCode, context.IncludeUserCode) = context.EndpointType switch
{
- // Only return a user code if the request is a device authorization request.
- OpenIddictServerEndpointType.Device => true,
+ // Only generate and return a user code if the request is a device authorization request.
+ OpenIddictServerEndpointType.Device => (true, true),
- _ => false
+ _ => (false, false)
};
return default;
@@ -1699,7 +1706,7 @@ namespace OpenIddict.Server
.AddFilter()
.AddFilter()
.UseScopedHandler()
- .SetOrder(EvaluateReturnedTokens.Descriptor.Order + 1_000)
+ .SetOrder(EvaluateTokenTypes.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
@@ -1714,7 +1721,7 @@ namespace OpenIddict.Server
Debug.Assert(context.Principal is not null, SR.GetResourceString(SR.ID4006));
// If no authorization code, device code or refresh token is returned, don't create an authorization.
- if (!context.IncludeAuthorizationCode && !context.IncludeDeviceCode && !context.IncludeRefreshToken)
+ if (!context.GenerateAuthorizationCode && !context.GenerateDeviceCode && !context.GenerateRefreshToken)
{
return;
}
@@ -1783,7 +1790,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(AttachAuthorization.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -1902,7 +1909,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(PrepareAccessTokenPrincipal.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2006,7 +2013,7 @@ namespace OpenIddict.Server
// Note: a device code principal is produced when a device code is included in the response or when a
// device code entry is replaced when processing a sign-in response sent to the verification endpoint.
- if (context.EndpointType != OpenIddictServerEndpointType.Verification && !context.IncludeDeviceCode)
+ if (context.EndpointType != OpenIddictServerEndpointType.Verification && !context.GenerateDeviceCode)
{
return default;
}
@@ -2069,7 +2076,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(PrepareDeviceCodePrincipal.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2153,7 +2160,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(PrepareRefreshTokenPrincipal.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2267,7 +2274,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(PrepareIdentityTokenPrincipal.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2582,7 +2589,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(ExtendRefreshTokenEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2650,7 +2657,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateAccessTokenEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2665,7 +2672,7 @@ namespace OpenIddict.Server
}
// If an access token was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.AccessToken))
+ if (!string.IsNullOrEmpty(context.AccessToken))
{
return default;
}
@@ -2739,9 +2746,10 @@ namespace OpenIddict.Server
additionalHeaderClaims: descriptor.AdditionalHeaderClaims);
}
- context.Response.AccessToken = token;
+ context.AccessToken = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6013), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6013), principal.GetClaim(Claims.JwtId),
+ context.AccessToken, principal.Claims);
return default;
}
@@ -2768,7 +2776,7 @@ namespace OpenIddict.Server
.AddFilter()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelAccessToken.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2782,7 +2790,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.AccessToken))
+ if (string.IsNullOrEmpty(context.AccessToken))
{
return;
}
@@ -2818,13 +2826,13 @@ namespace OpenIddict.Server
// Attach the generated token to the token entry, persist the change
// and replace the returned token by the reference identifier.
- descriptor.Payload = context.Response.AccessToken;
+ descriptor.Payload = context.AccessToken;
descriptor.Principal = principal;
descriptor.ReferenceId = Base64UrlEncoder.Encode(data);
await _tokenManager.UpdateAsync(token, descriptor);
- context.Response.AccessToken = descriptor.ReferenceId;
+ context.AccessToken = descriptor.ReferenceId;
context.Logger.LogTrace(SR.GetResourceString(SR.ID6014), identifier, descriptor.ReferenceId);
}
@@ -2856,7 +2864,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(ConvertReferenceAccessToken.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2924,7 +2932,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateAuthorizationCodeEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2939,7 +2947,7 @@ namespace OpenIddict.Server
}
// If an authorization code was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.Code))
+ if (!string.IsNullOrEmpty(context.AuthorizationCode))
{
return default;
}
@@ -2994,9 +3002,10 @@ namespace OpenIddict.Server
encryptingCredentials: context.Options.EncryptionCredentials.First(),
additionalHeaderClaims: descriptor.AdditionalHeaderClaims);
- context.Response.Code = token;
+ context.AuthorizationCode = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6016), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6016), principal.GetClaim(Claims.JwtId),
+ context.AuthorizationCode, principal.Claims);
return default;
}
@@ -3022,7 +3031,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelAuthorizationCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3036,7 +3045,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.Code))
+ if (string.IsNullOrEmpty(context.AuthorizationCode))
{
return;
}
@@ -3072,13 +3081,13 @@ namespace OpenIddict.Server
// Attach the generated token to the token entry, persist the change
// and replace the returned token by the reference identifier.
- descriptor.Payload = context.Response.Code;
+ descriptor.Payload = context.AuthorizationCode;
descriptor.Principal = principal;
descriptor.ReferenceId = Base64UrlEncoder.Encode(data);
await _tokenManager.UpdateAsync(token, descriptor);
- context.Response.Code = descriptor.ReferenceId;
+ context.AuthorizationCode = descriptor.ReferenceId;
context.Logger.LogTrace(SR.GetResourceString(SR.ID6017), identifier, descriptor.ReferenceId);
}
@@ -3110,7 +3119,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(ConvertReferenceAuthorizationCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3183,7 +3192,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateDeviceCodeEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3198,7 +3207,7 @@ namespace OpenIddict.Server
}
// If a device code was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.DeviceCode))
+ if (!string.IsNullOrEmpty(context.DeviceCode))
{
return default;
}
@@ -3253,9 +3262,10 @@ namespace OpenIddict.Server
encryptingCredentials: context.Options.EncryptionCredentials.First(),
additionalHeaderClaims: descriptor.AdditionalHeaderClaims);
- context.Response.DeviceCode = token;
+ context.DeviceCode = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6019), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6019), principal.GetClaim(Claims.JwtId),
+ context.DeviceCode, principal.Claims);
return default;
}
@@ -3282,7 +3292,7 @@ namespace OpenIddict.Server
.AddFilter()
.AddFilter()
// Note: device codes are always reference tokens.
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelDeviceCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3296,7 +3306,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.DeviceCode))
+ if (string.IsNullOrEmpty(context.DeviceCode))
{
return;
}
@@ -3337,13 +3347,13 @@ namespace OpenIddict.Server
// Attach the generated token to the token entry, persist the change
// and replace the returned token by the reference identifier.
- descriptor.Payload = context.Response.DeviceCode;
+ descriptor.Payload = context.DeviceCode;
descriptor.Principal = principal;
descriptor.ReferenceId = Base64UrlEncoder.Encode(data);
await _tokenManager.UpdateAsync(token, descriptor);
- context.Response.DeviceCode = descriptor.ReferenceId;
+ context.DeviceCode = descriptor.ReferenceId;
context.Logger.LogTrace(SR.GetResourceString(SR.ID6020), identifier, descriptor.ReferenceId);
}
@@ -3369,7 +3379,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(ConvertReferenceDeviceCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3383,7 +3393,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.DeviceCode))
+ if (string.IsNullOrEmpty(context.DeviceCode))
{
return;
}
@@ -3421,16 +3431,13 @@ namespace OpenIddict.Server
// Note: the lifetime is deliberately extended to give more time to the client to redeem the code.
descriptor.ExpirationDate = principal.GetExpirationDate();
- descriptor.Payload = context.Response.DeviceCode;
+ descriptor.Payload = context.DeviceCode;
descriptor.Principal = principal;
descriptor.Status = Statuses.Valid;
descriptor.Subject = principal.GetClaim(Claims.Subject);
await _tokenManager.UpdateAsync(token, descriptor);
- // Don't return the prepared device code directly from the verification endpoint.
- context.Response.DeviceCode = null;
-
context.Logger.LogTrace(SR.GetResourceString(SR.ID6021), await _tokenManager.GetIdAsync(token));
}
}
@@ -3461,7 +3468,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(UpdateReferenceDeviceCodeEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3529,7 +3536,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateRefreshTokenEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3544,7 +3551,7 @@ namespace OpenIddict.Server
}
// If a refresh token was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.RefreshToken))
+ if (!string.IsNullOrEmpty(context.RefreshToken))
{
return default;
}
@@ -3594,14 +3601,14 @@ namespace OpenIddict.Server
// Sign and encrypt the refresh token.
var token = context.Options.JsonWebTokenHandler.CreateToken(descriptor);
-
token = context.Options.JsonWebTokenHandler.EncryptToken(token,
encryptingCredentials: context.Options.EncryptionCredentials.First(),
additionalHeaderClaims: descriptor.AdditionalHeaderClaims);
- context.Response.RefreshToken = token;
+ context.RefreshToken = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6023), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6023), principal.GetClaim(Claims.JwtId),
+ context.RefreshToken, principal.Claims);
return default;
}
@@ -3628,7 +3635,7 @@ namespace OpenIddict.Server
.AddFilter()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelRefreshToken.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3642,7 +3649,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.RefreshToken))
+ if (string.IsNullOrEmpty(context.RefreshToken))
{
return;
}
@@ -3678,13 +3685,13 @@ namespace OpenIddict.Server
// Attach the generated token to the token entry, persist the change
// and replace the returned token by the reference identifier.
- descriptor.Payload = context.Response.RefreshToken;
+ descriptor.Payload = context.RefreshToken;
descriptor.Principal = principal;
descriptor.ReferenceId = Base64UrlEncoder.Encode(data);
await _tokenManager.UpdateAsync(token, descriptor);
- context.Response.RefreshToken = descriptor.ReferenceId;
+ context.RefreshToken = descriptor.ReferenceId;
context.Logger.LogTrace(SR.GetResourceString(SR.ID6024), identifier, descriptor.ReferenceId);
}
@@ -3700,8 +3707,8 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
- .AddFilter()
+ .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(ConvertReferenceRefreshToken.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3757,7 +3764,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(AttachDeviceCodeIdentifier.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3825,7 +3832,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateUserCodeEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3840,7 +3847,7 @@ namespace OpenIddict.Server
}
// If a user code was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.UserCode))
+ if (!string.IsNullOrEmpty(context.UserCode))
{
return default;
}
@@ -3885,9 +3892,10 @@ namespace OpenIddict.Server
encryptingCredentials: context.Options.EncryptionCredentials.First(),
additionalHeaderClaims: descriptor.AdditionalHeaderClaims);
- context.Response.UserCode = token;
+ context.UserCode = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6026), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6026), principal.GetClaim(Claims.JwtId),
+ context.UserCode, principal.Claims);
return default;
}
@@ -3914,7 +3922,7 @@ namespace OpenIddict.Server
.AddFilter()
.AddFilter()
// Note: user codes are always reference tokens.
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelUserCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -3928,7 +3936,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- if (string.IsNullOrEmpty(context.Response.UserCode))
+ if (string.IsNullOrEmpty(context.UserCode))
{
return;
}
@@ -3962,13 +3970,13 @@ namespace OpenIddict.Server
// Attach the generated token to the token entry, persist the change
// and replace the returned token by the reference identifier.
- descriptor.Payload = context.Response.UserCode;
+ descriptor.Payload = context.UserCode;
descriptor.Principal = principal;
descriptor.ReferenceId = await GenerateReferenceIdentifierAsync(_tokenManager);
await _tokenManager.UpdateAsync(token, descriptor);
- context.Response.UserCode = descriptor.ReferenceId;
+ context.UserCode = descriptor.ReferenceId;
context.Logger.LogTrace(SR.GetResourceString(SR.ID6027), identifier, descriptor.ReferenceId);
@@ -4015,7 +4023,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(ConvertReferenceUserCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -4035,8 +4043,7 @@ namespace OpenIddict.Server
throw new InvalidOperationException(SR.GetResourceString(SR.ID0022));
}
- if (string.IsNullOrEmpty(context.Response.AccessToken) &&
- string.IsNullOrEmpty(context.Response.Code))
+ if (string.IsNullOrEmpty(context.AccessToken) && string.IsNullOrEmpty(context.AuthorizationCode))
{
return default;
}
@@ -4054,18 +4061,18 @@ namespace OpenIddict.Server
throw new InvalidOperationException(SR.GetResourceString(SR.ID0267));
}
- if (!string.IsNullOrEmpty(context.Response.AccessToken))
+ if (!string.IsNullOrEmpty(context.AccessToken))
{
- var digest = hash.ComputeHash(Encoding.ASCII.GetBytes(context.Response.AccessToken));
+ var digest = hash.ComputeHash(Encoding.ASCII.GetBytes(context.AccessToken));
// Note: only the left-most half of the hash is used.
// See http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken
principal.SetClaim(Claims.AccessTokenHash, Base64UrlEncoder.Encode(digest, 0, digest.Length / 2));
}
- if (!string.IsNullOrEmpty(context.Response.Code))
+ if (!string.IsNullOrEmpty(context.AuthorizationCode))
{
- var digest = hash.ComputeHash(Encoding.ASCII.GetBytes(context.Response.Code));
+ var digest = hash.ComputeHash(Encoding.ASCII.GetBytes(context.AuthorizationCode));
// Note: only the left-most half of the hash is used.
// See http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken
@@ -4163,7 +4170,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(AttachTokenDigests.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -4231,7 +4238,7 @@ namespace OpenIddict.Server
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(CreateIdentityTokenEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -4246,7 +4253,7 @@ namespace OpenIddict.Server
}
// If an identity token was already attached by another handler, don't overwrite it.
- if (!string.IsNullOrEmpty(context.Response.IdToken))
+ if (!string.IsNullOrEmpty(context.IdentityToken))
{
return default;
}
@@ -4306,9 +4313,10 @@ namespace OpenIddict.Server
// Sign and attach the identity token.
var token = context.Options.JsonWebTokenHandler.CreateToken(descriptor);
- context.Response.IdToken = token;
+ context.IdentityToken = token;
- context.Logger.LogTrace(SR.GetResourceString(SR.ID6029), principal.GetClaim(Claims.JwtId), token, principal.Claims);
+ context.Logger.LogTrace(SR.GetResourceString(SR.ID6029), principal.GetClaim(Claims.JwtId),
+ context.IdentityToken, principal.Claims);
return default;
}
@@ -4329,7 +4337,7 @@ namespace OpenIddict.Server
// but the default CreateReferenceUserCodeEntry that creates the user code
// reference identifiers only works when the degraded mode is disabled.
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelIdentityToken.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -4347,7 +4355,7 @@ namespace OpenIddict.Server
// appended before each new block of 4 integers. These dashes are expected to be
// stripped from the user codes when receiving them at the verification endpoint.
- var builder = new StringBuilder(context.Response.UserCode);
+ var builder = new StringBuilder(context.UserCode);
if (builder.Length % 4 != 0)
{
return default;
@@ -4361,24 +4369,23 @@ namespace OpenIddict.Server
}
}
- context.Response.UserCode = builder.ToString();
+ context.UserCode = builder.ToString();
return default;
}
}
///
- /// Contains the logic responsible of attaching additional access token properties to the sign-in response.
+ /// Contains the logic responsible of attaching the tokens and their metadata to the sign-in response.
///
- public class AttachAccessTokenProperties : IOpenIddictServerHandler
+ public class AttachTokenParameters : IOpenIddictServerHandler
{
///
/// Gets the default descriptor definition assigned to this handler.
///
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
- .UseSingletonHandler()
+ .UseSingletonHandler()
.SetOrder(BeautifyUserCode.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
.Build();
@@ -4391,73 +4398,78 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- Debug.Assert(context.AccessTokenPrincipal is not null, SR.GetResourceString(SR.ID4006));
+ if (context.IncludeAccessToken)
+ {
+ context.Response.AccessToken = context.AccessToken;
+ context.Response.TokenType = TokenTypes.Bearer;
- context.Response.TokenType = TokenTypes.Bearer;
+ // If the principal is available, attach additional metadata.
+ if (context.AccessTokenPrincipal is not null)
+ {
+ // If an expiration date was set on the access token principal, return it to the client application.
+ var date = context.AccessTokenPrincipal.GetExpirationDate();
+ if (date.HasValue && date.Value > DateTimeOffset.UtcNow)
+ {
+ context.Response.ExpiresIn = (long) ((date.Value - DateTimeOffset.UtcNow).TotalSeconds + .5);
+ }
- // If an expiration date was set on the access token principal, return it to the client application.
- var date = context.AccessTokenPrincipal.GetExpirationDate();
- if (date.HasValue && date.Value > DateTimeOffset.UtcNow)
- {
- context.Response.ExpiresIn = (long) ((date.Value - DateTimeOffset.UtcNow).TotalSeconds + .5);
+ // If the granted access token scopes differ from the requested scopes, return the granted scopes
+ // list as a parameter to inform the client application of the fact the scopes set will be reduced.
+ var scopes = new HashSet(context.AccessTokenPrincipal.GetScopes(), StringComparer.Ordinal);
+ if ((context.EndpointType == OpenIddictServerEndpointType.Token && context.Request.IsAuthorizationCodeGrantType()) ||
+ !scopes.SetEquals(context.Request.GetScopes()))
+ {
+ context.Response.Scope = string.Join(" ", scopes);
+ }
+ }
}
- // If the granted access token scopes differ from the requested scopes, return the granted scopes
- // list as a parameter to inform the client application of the fact the scopes set will be reduced.
- var scopes = new HashSet(context.AccessTokenPrincipal.GetScopes(), StringComparer.Ordinal);
- if ((context.EndpointType == OpenIddictServerEndpointType.Token && context.Request.IsAuthorizationCodeGrantType()) ||
- !scopes.SetEquals(context.Request.GetScopes()))
+ if (context.IncludeAuthorizationCode)
{
- context.Response.Scope = string.Join(" ", scopes);
+ context.Response.Code = context.AuthorizationCode;
}
- return default;
- }
- }
+ if (context.IncludeDeviceCode)
+ {
+ context.Response.DeviceCode = context.DeviceCode;
- ///
- /// Contains the logic responsible of attaching additional device code properties to the sign-in response.
- ///
- public class AttachDeviceCodeProperties : IOpenIddictServerHandler
- {
- ///
- /// Gets the default descriptor definition assigned to this handler.
- ///
- public static OpenIddictServerHandlerDescriptor Descriptor { get; }
- = OpenIddictServerHandlerDescriptor.CreateBuilder()
- .AddFilter()
- .UseSingletonHandler()
- .SetOrder(AttachAccessTokenProperties.Descriptor.Order + 1_000)
- .SetType(OpenIddictServerHandlerType.BuiltIn)
- .Build();
+ // If the principal is available, attach additional metadata.
+ if (context.DeviceCodePrincipal is not null)
+ {
+ // If an expiration date was set on the device code principal, return it to the client application.
+ var date = context.DeviceCodePrincipal.GetExpirationDate();
+ if (date.HasValue && date.Value > DateTimeOffset.UtcNow)
+ {
+ context.Response.ExpiresIn = (long) ((date.Value - DateTimeOffset.UtcNow).TotalSeconds + .5);
+ }
+ }
+ }
- ///
- public ValueTask HandleAsync(ProcessSignInContext context)
- {
- if (context is null)
+ if (context.IncludeIdentityToken)
{
- throw new ArgumentNullException(nameof(context));
+ context.Response.IdToken = context.IdentityToken;
}
- Debug.Assert(context.DeviceCodePrincipal is not null, SR.GetResourceString(SR.ID4006));
-
- var address = GetEndpointAbsoluteUri(context.Issuer, context.Options.VerificationEndpointUris.FirstOrDefault());
- if (address is not null)
+ if (context.IncludeRefreshToken)
{
- var builder = new UriBuilder(address)
- {
- Query = string.Concat(Parameters.UserCode, "=", context.Response.UserCode)
- };
-
- context.Response[Parameters.VerificationUri] = address.AbsoluteUri;
- context.Response[Parameters.VerificationUriComplete] = builder.Uri.AbsoluteUri;
+ context.Response.RefreshToken = context.RefreshToken;
}
- // If an expiration date was set on the device code principal, return it to the client application.
- var date = context.DeviceCodePrincipal.GetExpirationDate();
- if (date.HasValue && date.Value > DateTimeOffset.UtcNow)
+ if (context.IncludeUserCode)
{
- context.Response.ExpiresIn = (long) ((date.Value - DateTimeOffset.UtcNow).TotalSeconds + .5);
+ context.Response.UserCode = context.UserCode;
+
+ var address = GetEndpointAbsoluteUri(context.Issuer, context.Options.VerificationEndpointUris.FirstOrDefault());
+ if (address is not null)
+ {
+ var builder = new UriBuilder(address)
+ {
+ Query = string.Concat(Parameters.UserCode, "=", context.UserCode)
+ };
+
+ context.Response[Parameters.VerificationUri] = address.AbsoluteUri;
+ context.Response[Parameters.VerificationUriComplete] = builder.Uri.AbsoluteUri;
+ }
}
return default;
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
index e029ce66..57d6f38c 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
@@ -1608,15 +1608,15 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
- context.IncludeAccessToken = false;
- context.IncludeAuthorizationCode = true;
- context.IncludeIdentityToken = true;
- context.IncludeRefreshToken = true;
+ context.GenerateAccessToken = context.IncludeAccessToken = false;
+ context.GenerateAuthorizationCode = context.IncludeAuthorizationCode = true;
+ context.GenerateIdentityToken = context.IncludeIdentityToken = true;
+ context.GenerateRefreshToken = context.IncludeRefreshToken = true;
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1662,12 +1662,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAuthorizationCode);
Assert.True(context.IncludeAuthorizationCode);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1801,12 +1802,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1856,12 +1858,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1908,12 +1911,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1951,12 +1955,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -1995,12 +2000,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2040,12 +2046,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateAccessToken);
Assert.True(context.IncludeAccessToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2114,12 +2121,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.False(context.GenerateRefreshToken);
Assert.False(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2168,12 +2176,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateRefreshToken);
Assert.True(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2221,12 +2230,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateRefreshToken);
Assert.True(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2255,12 +2265,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateRefreshToken);
Assert.True(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
options.AddEventHandler(builder =>
@@ -2300,12 +2311,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateRefreshToken);
Assert.True(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
options.AddEventHandler(builder =>
@@ -2346,12 +2358,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateRefreshToken);
Assert.True(context.IncludeRefreshToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
options.AddEventHandler(builder =>
@@ -2398,12 +2411,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.False(context.GenerateIdentityToken);
Assert.False(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2446,12 +2460,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2502,12 +2517,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2555,12 +2571,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2589,12 +2606,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
options.AddEventHandler(builder =>
@@ -2643,12 +2661,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});
@@ -2689,12 +2708,13 @@ namespace OpenIddict.Server.IntegrationTests
{
builder.UseInlineHandler(context =>
{
+ Assert.True(context.GenerateIdentityToken);
Assert.True(context.IncludeIdentityToken);
return default;
});
- builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
+ builder.SetOrder(EvaluateTokenTypes.Descriptor.Order + 500);
});
});