diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs
index a234a7b2..ade34461 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionBuilder.cs
@@ -81,11 +81,39 @@ namespace Microsoft.Extensions.DependencyInjection
}
///
- /// Configures OpenIddict to use the default token format (JWT) when issuing new tokens.
+ /// Configures OpenIddict to use the default token format (JWT) when issuing new access tokens.
///
/// The .
- public OpenIddictServerDataProtectionBuilder PreferDefaultTokenFormat()
- => Configure(options => options.PreferDefaultTokenFormat = true);
+ public OpenIddictServerDataProtectionBuilder PreferDefaultAccessTokenFormat()
+ => Configure(options => options.PreferDefaultAccessTokenFormat = true);
+
+ ///
+ /// Configures OpenIddict to use the default token format (JWT) when issuing new authorization codes.
+ ///
+ /// The .
+ public OpenIddictServerDataProtectionBuilder PreferDefaultAuthorizationCodeFormat()
+ => Configure(options => options.PreferDefaultAuthorizationCodeFormat = true);
+
+ ///
+ /// Configures OpenIddict to use the default token format (JWT) when issuing new device codes.
+ ///
+ /// The .
+ public OpenIddictServerDataProtectionBuilder PreferDefaultDeviceCodeFormat()
+ => Configure(options => options.PreferDefaultDeviceCodeFormat = true);
+
+ ///
+ /// Configures OpenIddict to use the default token format (JWT) when issuing new refresh tokens.
+ ///
+ /// The .
+ public OpenIddictServerDataProtectionBuilder PreferDefaultRefreshTokenFormat()
+ => Configure(options => options.PreferDefaultRefreshTokenFormat = true);
+
+ ///
+ /// Configures OpenIddict to use the default token format (JWT) when issuing new user codes.
+ ///
+ /// The .
+ public OpenIddictServerDataProtectionBuilder PreferDefaultUserCodeFormat()
+ => Configure(options => options.PreferDefaultUserCodeFormat = true);
///
/// Determines whether the specified object is equal to the current object.
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs
index b90c3575..a32af009 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionExtensions.cs
@@ -42,7 +42,11 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.TryAdd(DefaultHandlers.Select(descriptor => descriptor.ServiceDescriptor));
// Register the built-in filter used by the default OpenIddict Data Protection event handlers.
- builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
+ builder.Services.TryAddSingleton();
// Note: TryAddEnumerable() is used here to ensure the initializers are registered only once.
builder.Services.TryAddEnumerable(new[]
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs
index f15ce0dd..5c96ec19 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlerFilters.cs
@@ -20,13 +20,14 @@ namespace OpenIddict.Server.DataProtection
public static class OpenIddictServerDataProtectionHandlerFilters
{
///
- /// Represents a filter that excludes the associated handlers if OpenIddict was not configured to issue Data Protection tokens.
+ /// Represents a filter that excludes the associated handlers if OpenIddict
+ /// was not configured to issue ASP.NET Core Data Protection access tokens.
///
- public class RequireDataProtectionFormatEnabled : IOpenIddictServerHandlerFilter
+ public class RequireDataProtectionAccessTokenFormatEnabled : IOpenIddictServerHandlerFilter
{
private readonly IOptionsMonitor _options;
- public RequireDataProtectionFormatEnabled([NotNull] IOptionsMonitor options)
+ public RequireDataProtectionAccessTokenFormatEnabled([NotNull] IOptionsMonitor options)
=> _options = options;
public ValueTask IsActiveAsync([NotNull] BaseContext context)
@@ -36,7 +37,95 @@ namespace OpenIddict.Server.DataProtection
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(!_options.CurrentValue.PreferDefaultTokenFormat);
+ return new ValueTask(!_options.CurrentValue.PreferDefaultAccessTokenFormat);
+ }
+ }
+
+ ///
+ /// Represents a filter that excludes the associated handlers if OpenIddict
+ /// was not configured to issue ASP.NET Core Data Protection authorization codes.
+ ///
+ public class RequireDataProtectionAuthorizationCodeFormatEnabled : IOpenIddictServerHandlerFilter
+ {
+ private readonly IOptionsMonitor _options;
+
+ public RequireDataProtectionAuthorizationCodeFormatEnabled([NotNull] IOptionsMonitor options)
+ => _options = options;
+
+ public ValueTask IsActiveAsync([NotNull] BaseContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ return new ValueTask(!_options.CurrentValue.PreferDefaultAuthorizationCodeFormat);
+ }
+ }
+
+ ///
+ /// Represents a filter that excludes the associated handlers if OpenIddict
+ /// was not configured to issue ASP.NET Core Data Protection device codes.
+ ///
+ public class RequireDataProtectionDeviceCodeFormatEnabled : IOpenIddictServerHandlerFilter
+ {
+ private readonly IOptionsMonitor _options;
+
+ public RequireDataProtectionDeviceCodeFormatEnabled([NotNull] IOptionsMonitor options)
+ => _options = options;
+
+ public ValueTask IsActiveAsync([NotNull] BaseContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ return new ValueTask(!_options.CurrentValue.PreferDefaultDeviceCodeFormat);
+ }
+ }
+
+ ///
+ /// Represents a filter that excludes the associated handlers if OpenIddict
+ /// was not configured to issue ASP.NET Core Data Protection refresh tokens.
+ ///
+ public class RequireDataProtectionRefreshTokenFormatEnabled : IOpenIddictServerHandlerFilter
+ {
+ private readonly IOptionsMonitor _options;
+
+ public RequireDataProtectionRefreshTokenFormatEnabled([NotNull] IOptionsMonitor options)
+ => _options = options;
+
+ public ValueTask IsActiveAsync([NotNull] BaseContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ return new ValueTask(!_options.CurrentValue.PreferDefaultRefreshTokenFormat);
+ }
+ }
+
+ ///
+ /// Represents a filter that excludes the associated handlers if OpenIddict
+ /// was not configured to issue ASP.NET Core Data Protection user codes.
+ ///
+ public class RequireDataProtectionUserCodeFormatEnabled : IOpenIddictServerHandlerFilter
+ {
+ private readonly IOptionsMonitor _options;
+
+ public RequireDataProtectionUserCodeFormatEnabled([NotNull] IOptionsMonitor options)
+ => _options = options;
+
+ public ValueTask IsActiveAsync([NotNull] BaseContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ return new ValueTask(!_options.CurrentValue.PreferDefaultUserCodeFormat);
}
}
}
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
index 67f31526..8bd6cb0a 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionHandlers.cs
@@ -178,7 +178,7 @@ namespace OpenIddict.Server.DataProtection
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelAccessToken.Descriptor.Order - 500)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -205,7 +205,7 @@ namespace OpenIddict.Server.DataProtection
}
// Create a Data Protection protector using the provider registered in the options.
- var protector = context.Options.UseReferenceTokens ?
+ var protector = context.Options.UseReferenceAccessTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
Handlers.Server, Formats.AccessToken, Features.ReferenceTokens, Schemes.Server) :
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@@ -243,7 +243,7 @@ namespace OpenIddict.Server.DataProtection
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelAuthorizationCode.Descriptor.Order - 500)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -270,7 +270,7 @@ namespace OpenIddict.Server.DataProtection
}
// Create a Data Protection protector using the provider registered in the options.
- var protector = context.Options.UseReferenceTokens ?
+ var protector = !context.Options.DisableTokenStorage ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
Handlers.Server, Formats.AuthorizationCode, Features.ReferenceTokens, Schemes.Server) :
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@@ -308,7 +308,7 @@ namespace OpenIddict.Server.DataProtection
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelDeviceCode.Descriptor.Order - 500)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -373,7 +373,7 @@ namespace OpenIddict.Server.DataProtection
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelRefreshToken.Descriptor.Order - 500)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -400,7 +400,7 @@ namespace OpenIddict.Server.DataProtection
}
// Create a Data Protection protector using the provider registered in the options.
- var protector = context.Options.UseReferenceTokens ?
+ var protector = context.Options.UseReferenceRefreshTokens ?
_options.CurrentValue.DataProtectionProvider.CreateProtector(
Handlers.Server, Formats.RefreshToken, Features.ReferenceTokens, Schemes.Server) :
_options.CurrentValue.DataProtectionProvider.CreateProtector(
@@ -438,7 +438,7 @@ namespace OpenIddict.Server.DataProtection
public static OpenIddictServerHandlerDescriptor Descriptor { get; }
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseSingletonHandler()
.SetOrder(GenerateIdentityModelUserCode.Descriptor.Order - 500)
.SetType(OpenIddictServerHandlerType.BuiltIn)
diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs
index 3ed0ab8a..3c495d31 100644
--- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs
+++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionOptions.cs
@@ -29,9 +29,33 @@ namespace OpenIddict.Server.DataProtection
= new OpenIddictServerDataProtectionFormatter();
///
- /// Gets or sets a boolean indicating whether the default token format should be
- /// used when issuing new tokens. This property is set to false by default.
+ /// Gets or sets a boolean indicating whether the default access token format should be
+ /// used when issuing new access tokens. This property is set to false by default.
///
- public bool PreferDefaultTokenFormat { get; set; }
+ public bool PreferDefaultAccessTokenFormat { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the default authorization code format should be
+ /// used when issuing new authorization codes. This property is set to false by default.
+ ///
+ public bool PreferDefaultAuthorizationCodeFormat { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the default device code format should be
+ /// used when issuing new device codes. This property is set to false by default.
+ ///
+ public bool PreferDefaultDeviceCodeFormat { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the default refresh token format should be
+ /// used when issuing new refresh tokens. This property is set to false by default.
+ ///
+ public bool PreferDefaultRefreshTokenFormat { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether the default user code format should be
+ /// used when issuing new user codes. This property is set to false by default.
+ ///
+ public bool PreferDefaultUserCodeFormat { get; set; }
}
}
diff --git a/src/OpenIddict.Server/OpenIddictServerBuilder.cs b/src/OpenIddict.Server/OpenIddictServerBuilder.cs
index 80006457..69f85b2c 100644
--- a/src/OpenIddict.Server/OpenIddictServerBuilder.cs
+++ b/src/OpenIddict.Server/OpenIddictServerBuilder.cs
@@ -1782,15 +1782,26 @@ namespace Microsoft.Extensions.DependencyInjection
}
///
- /// Configures OpenIddict to use reference tokens, so that the token and code payloads
+ /// Configures OpenIddict to use reference tokens, so that the access token payloads
/// are stored in the database (only an identifier is returned to the client application).
/// Enabling this option is useful when storing a very large number of claims in the tokens,
/// but it is RECOMMENDED to enable column encryption in the database or use the ASP.NET Core
/// Data Protection integration, that provides additional protection against token leakage.
///
/// The .
- public OpenIddictServerBuilder UseReferenceTokens()
- => Configure(options => options.UseReferenceTokens = true);
+ public OpenIddictServerBuilder UseReferenceAccessTokens()
+ => Configure(options => options.UseReferenceAccessTokens = true);
+
+ ///
+ /// Configures OpenIddict to use reference tokens, so that the refresh token payloads
+ /// are stored in the database (only an identifier is returned to the client application).
+ /// Enabling this option is useful when storing a very large number of claims in the tokens,
+ /// but it is RECOMMENDED to enable column encryption in the database or use the ASP.NET Core
+ /// Data Protection integration, that provides additional protection against token leakage.
+ ///
+ /// The .
+ public OpenIddictServerBuilder UseReferenceRefreshTokens()
+ => Configure(options => options.UseReferenceRefreshTokens = true);
///
/// Configures OpenIddict to use rolling refresh tokens. When this option is enabled,
@@ -1798,8 +1809,8 @@ namespace Microsoft.Extensions.DependencyInjection
/// one is automatically revoked unless token storage was explicitly disabled).
///
/// The .
- public OpenIddictServerBuilder UseRollingTokens()
- => Configure(options => options.UseRollingTokens = true);
+ public OpenIddictServerBuilder UseRollingRefreshTokens()
+ => Configure(options => options.UseRollingRefreshTokens = true);
///
/// Determines whether the specified object is equal to the current object.
diff --git a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
index 6a3848bb..0c3f2195 100644
--- a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
+++ b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs
@@ -96,12 +96,12 @@ namespace OpenIddict.Server
throw new InvalidOperationException("The revocation endpoint cannot be enabled when token storage is disabled.");
}
- if (options.UseReferenceTokens)
+ if (options.UseReferenceAccessTokens || options.UseReferenceRefreshTokens)
{
throw new InvalidOperationException("Reference tokens cannot be used when disabling token storage.");
}
- if (options.UseSlidingExpiration && !options.UseRollingTokens)
+ if (options.UseSlidingExpiration && !options.UseRollingRefreshTokens)
{
throw new InvalidOperationException(new StringBuilder()
.Append("Sliding expiration must be disabled when turning off token storage if rolling tokens are not used.")
diff --git a/src/OpenIddict.Server/OpenIddictServerExtensions.cs b/src/OpenIddict.Server/OpenIddictServerExtensions.cs
index 01a99268..c72962de 100644
--- a/src/OpenIddict.Server/OpenIddictServerExtensions.cs
+++ b/src/OpenIddict.Server/OpenIddictServerExtensions.cs
@@ -54,10 +54,11 @@ 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();
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 6b239cc8..85bf1572 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlerFilters.cs
@@ -176,9 +176,9 @@ namespace OpenIddict.Server
}
///
- /// Represents a filter that excludes the associated handlers if reference tokens are disabled.
+ /// Represents a filter that excludes the associated handlers if reference access tokens are disabled.
///
- public class RequireReferenceTokensEnabled : IOpenIddictServerHandlerFilter
+ public class RequireReferenceAccessTokensEnabled : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync([NotNull] BaseContext context)
{
@@ -187,7 +187,23 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.Options.UseReferenceTokens);
+ return new ValueTask(context.Options.UseReferenceAccessTokens);
+ }
+ }
+
+ ///
+ /// Represents a filter that excludes the associated handlers if reference refresh tokens are disabled.
+ ///
+ public class RequireReferenceRefreshTokensEnabled : IOpenIddictServerHandlerFilter
+ {
+ public ValueTask IsActiveAsync([NotNull] BaseContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ return new ValueTask(context.Options.UseReferenceRefreshTokens);
}
}
@@ -219,14 +235,14 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(!context.Options.UseRollingTokens);
+ return new ValueTask(!context.Options.UseRollingRefreshTokens);
}
}
///
- /// Represents a filter that excludes the associated handlers if rolling tokens were not enabled.
+ /// Represents a filter that excludes the associated handlers if rolling refresh tokens were not enabled.
///
- public class RequireRollingTokensEnabled : IOpenIddictServerHandlerFilter
+ public class RequireRollingRefreshTokensEnabled : IOpenIddictServerHandlerFilter
{
public ValueTask IsActiveAsync([NotNull] BaseContext context)
{
@@ -235,7 +251,7 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(context));
}
- return new ValueTask(context.Options.UseRollingTokens);
+ return new ValueTask(context.Options.UseRollingRefreshTokens);
}
}
diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
index 86ef3c7f..45c7b52a 100644
--- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs
+++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs
@@ -1764,7 +1764,8 @@ namespace OpenIddict.Server
OpenIddictServerEndpointType.Token when !context.Principal.HasScope(Scopes.OfflineAccess) => false,
// 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.UseRollingTokens,
+ 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,
@@ -2547,7 +2548,7 @@ namespace OpenIddict.Server
return;
}
- if (context.Request.IsRefreshTokenGrantType() && !context.Options.UseRollingTokens)
+ if (context.Request.IsRefreshTokenGrantType() && !context.Options.UseRollingRefreshTokens)
{
return;
}
@@ -2615,7 +2616,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.UseScopedHandler()
.SetOrder(RedeemTokenEntry.Descriptor.Order + 1_000)
.SetType(OpenIddictServerHandlerType.BuiltIn)
@@ -2980,7 +2981,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelAccessToken.Descriptor.Order + 1_000)
@@ -3266,7 +3267,6 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
.AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelAuthorizationCode.Descriptor.Order + 1_000)
@@ -3945,7 +3945,7 @@ namespace OpenIddict.Server
= OpenIddictServerHandlerDescriptor.CreateBuilder()
.AddFilter()
.AddFilter()
- .AddFilter()
+ .AddFilter()
.AddFilter()
.UseScopedHandler()
.SetOrder(GenerateIdentityModelRefreshToken.Descriptor.Order + 1_000)
diff --git a/src/OpenIddict.Server/OpenIddictServerOptions.cs b/src/OpenIddict.Server/OpenIddictServerOptions.cs
index 92b5a349..9e9a4512 100644
--- a/src/OpenIddict.Server/OpenIddictServerOptions.cs
+++ b/src/OpenIddict.Server/OpenIddictServerOptions.cs
@@ -334,15 +334,26 @@ namespace OpenIddict.Server
};
///
- /// Gets or sets a boolean indicating whether reference tokens should be used.
- /// When set to true, token and code payloads are stored in the database
- /// and a crypto-secure random identifier is returned to the client application.
+ /// Gets or sets a boolean indicating whether reference access tokens should be used.
+ /// When set to true, the token payload is stored in the database and a
+ /// crypto-secure random identifier is returned to the client application.
/// Enabling this option is useful when storing a very large number of claims
/// in the tokens, but it is RECOMMENDED to enable column encryption
/// in the database or use the ASP.NET Core Data Protection integration,
/// that provides additional protection against token leakage.
///
- public bool UseReferenceTokens { get; set; }
+ public bool UseReferenceAccessTokens { get; set; }
+
+ ///
+ /// Gets or sets a boolean indicating whether reference refresh tokens should be used.
+ /// When set to true, the token payload is stored in the database and a
+ /// crypto-secure random identifier is returned to the client application.
+ /// Enabling this option is useful when storing a very large number of claims
+ /// in the tokens, but it is RECOMMENDED to enable column encryption
+ /// in the database or use the ASP.NET Core Data Protection integration,
+ /// that provides additional protection against token leakage.
+ ///
+ public bool UseReferenceRefreshTokens { get; set; }
///
/// Gets or sets a boolean indicating whether rolling tokens should be used.
@@ -352,6 +363,6 @@ namespace OpenIddict.Server
/// refresh token request (and the previous one is automatically revoked
/// unless token storage was explicitly disabled in the options).
///
- public bool UseRollingTokens { get; set; }
+ public bool UseRollingRefreshTokens { get; set; }
}
}
diff --git a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs
index 96aced58..1bc085bc 100644
--- a/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs
+++ b/src/OpenIddict.Validation.ServerIntegration/OpenIddictValidationServerIntegrationConfiguration.cs
@@ -59,8 +59,8 @@ namespace OpenIddict.Validation.ServerIntegration
options.EncryptionCredentials.Add(credentials);
}
- // Note: token entry validation must be enabled to be able to validate reference tokens.
- options.EnableTokenEntryValidation = _options.CurrentValue.UseReferenceTokens;
+ // Note: token entry validation must be enabled to be able to validate reference access tokens.
+ options.EnableTokenEntryValidation = _options.CurrentValue.UseReferenceAccessTokens;
}
///
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
index 16ae6f61..795c7515 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Introspection.cs
@@ -1217,8 +1217,6 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
- options.UseReferenceTokens();
-
options.Services.AddSingleton(CreateApplicationManager(mock =>
{
var application = new OpenIddictApplication();
@@ -1329,7 +1327,6 @@ namespace OpenIddict.Server.FunctionalTests
options.Services.AddSingleton(manager);
options.DisableAuthorizationStorage();
- options.UseReferenceTokens();
});
await using var client = await server.CreateClientAsync();
@@ -1421,8 +1418,6 @@ namespace OpenIddict.Server.FunctionalTests
options.Services.AddSingleton(manager);
- options.UseReferenceTokens();
-
options.RemoveEventHandler(NormalizeErrorResponse.Descriptor);
});
@@ -1521,8 +1516,6 @@ namespace OpenIddict.Server.FunctionalTests
options.Services.AddSingleton(manager);
- options.UseReferenceTokens();
-
options.RemoveEventHandler(NormalizeErrorResponse.Descriptor);
});
@@ -1608,8 +1601,6 @@ namespace OpenIddict.Server.FunctionalTests
options.Services.AddSingleton(manager);
- options.UseReferenceTokens();
-
options.RemoveEventHandler(NormalizeErrorResponse.Descriptor);
});
diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
index 86e3d06a..991d6f0c 100644
--- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
+++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs
@@ -2888,7 +2888,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
options.EnableDegradedMode();
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.AddEventHandler(builder =>
{
@@ -2940,7 +2940,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
options.EnableDegradedMode();
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.AddEventHandler(builder =>
{
@@ -2984,7 +2984,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
options.EnableDegradedMode();
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.AddEventHandler(builder =>
{
@@ -3240,7 +3240,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.DisableAuthorizationStorage();
options.AddEventHandler(builder =>
@@ -3307,7 +3307,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.DisableAuthorizationStorage();
options.AddEventHandler(builder =>
@@ -3456,7 +3456,7 @@ namespace OpenIddict.Server.FunctionalTests
await using var server = await CreateServerAsync(options =>
{
- options.UseRollingTokens();
+ options.UseRollingRefreshTokens();
options.AddEventHandler(builder =>
{
@@ -3969,6 +3969,9 @@ namespace OpenIddict.Server.FunctionalTests
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny()))
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56");
+
+ mock.Setup(manager => manager.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()))
+ .ReturnsAsync(token);
}));
options.Services.AddSingleton(manager);
@@ -4042,6 +4045,9 @@ namespace OpenIddict.Server.FunctionalTests
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny()))
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56");
+
+ mock.Setup(manager => manager.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny()))
+ .ReturnsAsync(token);
}));
options.Services.AddSingleton(manager);
diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
index 61fcf1f7..3177488e 100644
--- a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
+++ b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
@@ -35,7 +35,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Action> configuration = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddEventHandler(configuration));
Assert.Equal(nameof(configuration), exception.ParamName);
}
@@ -48,7 +48,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
OpenIddictServerHandlerDescriptor descriptor = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddEventHandler(descriptor));
Assert.Equal(nameof(descriptor), exception.ParamName);
}
@@ -136,7 +136,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
EncryptingCredentials credentials = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddEncryptionCredentials(credentials));
Assert.Equal(nameof(credentials), exception.ParamName);
}
@@ -149,7 +149,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
SecurityKey key = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddEncryptionKey(key));
Assert.Equal(nameof(key), exception.ParamName);
}
@@ -163,7 +163,7 @@ namespace OpenIddict.Server.Tests
var key = new Mock();
key.SetupGet(x => x.PrivateKeyStatus).Returns(PrivateKeyStatus.DoesNotExist);
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddEncryptionKey(key.Object));
Assert.Equal("The asymmetric encryption key doesn't contain the required private key.", exception.Message);
}
@@ -194,7 +194,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
OpenIddictServerHandlerDescriptor descriptor = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.RemoveEventHandler(descriptor));
Assert.Equal(nameof(descriptor), exception.ParamName);
}
@@ -242,7 +242,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Action configuration = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.Configure(configuration));
Assert.Equal(nameof(configuration), exception.ParamName);
}
@@ -271,7 +271,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
X500DistinguishedName subject = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AddDevelopmentEncryptionCertificate(subject));
Assert.Equal(nameof(subject), exception.ParamName);
}
@@ -455,7 +455,7 @@ namespace OpenIddict.Server.Tests
var services = CreateServices();
var builder = CreateBuilder(services);
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.AllowCustomFlow(type));
Assert.Equal(nameof(type), exception.ParamName);
Assert.Contains("The grant type cannot be null or empty.", exception.Message);
@@ -533,7 +533,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetConfigurationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -546,7 +546,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetConfigurationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -562,7 +562,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetConfigurationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -608,7 +608,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetDeviceEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -621,7 +621,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetDeviceEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -635,7 +635,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetDeviceEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -697,7 +697,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetCryptographyEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -710,7 +710,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetCryptographyEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -724,7 +724,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetCryptographyEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -818,7 +818,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetAuthorizationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -831,7 +831,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetAuthorizationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -845,7 +845,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetAuthorizationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -891,7 +891,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetIntrospectionEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -904,7 +904,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetIntrospectionEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -918,7 +918,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetIntrospectionEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -964,7 +964,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetLogoutEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -977,7 +977,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetLogoutEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -991,7 +991,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetLogoutEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -1037,7 +1037,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetRevocationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1050,7 +1050,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetRevocationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1064,7 +1064,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetRevocationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -1126,7 +1126,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetTokenEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1139,7 +1139,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetTokenEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1153,7 +1153,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetTokenEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -1199,7 +1199,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetUserinfoEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1212,7 +1212,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetUserinfoEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1226,7 +1226,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = {new Uri(uri), };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetUserinfoEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);
@@ -1526,7 +1526,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] claims = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.RegisterClaims(claims));
Assert.Equal(nameof(claims), exception.ParamName);
}
@@ -1541,7 +1541,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] claims = { claim };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.RegisterClaims(claims));
Assert.Equal(nameof(claims), exception.ParamName);
Assert.Contains("Claims cannot be null or empty.", exception.Message);
@@ -1572,7 +1572,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] scopes = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.RegisterScopes(scopes));
Assert.Equal(nameof(scopes), exception.ParamName);
}
@@ -1587,26 +1587,58 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] scopes = { scope };
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.RegisterScopes(scopes));
Assert.Equal(nameof(scopes), exception.ParamName);
Assert.Contains("Scopes cannot be null or empty.", exception.Message);
}
[Fact]
- public void UseReferenceTokens_ReferenceTokensAreEnabled()
+ public void UseReferenceAccessTokens_ReferenceAccessTokensAreEnabled()
+ {
+ // Arrange
+ var services = CreateServices();
+ var builder = CreateBuilder(services);
+
+ // Act
+ builder.UseReferenceAccessTokens();
+
+ var options = GetOptions(services);
+
+ // Assert
+ Assert.True(options.UseReferenceAccessTokens);
+ }
+
+ [Fact]
+ public void UseReferenceRefreshTokens_ReferenceRefreshTokensAreEnabled()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
- builder.UseReferenceTokens();
+ builder.UseReferenceRefreshTokens();
var options = GetOptions(services);
// Assert
- Assert.True(options.UseReferenceTokens);
+ Assert.True(options.UseReferenceRefreshTokens);
+ }
+
+ [Fact]
+ public void UseRollingRefreshTokens_RollingRefreshTokensAreEnabled()
+ {
+ // Arrange
+ var services = CreateServices();
+ var builder = CreateBuilder(services);
+
+ // Act
+ builder.UseRollingRefreshTokens();
+
+ var options = GetOptions(services);
+
+ // Assert
+ Assert.True(options.UseRollingRefreshTokens);
}
[Fact]
@@ -1617,7 +1649,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetVerificationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1630,7 +1662,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
string[] addresses = null;
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetVerificationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
}
@@ -1661,7 +1693,7 @@ namespace OpenIddict.Server.Tests
var builder = CreateBuilder(services);
Uri[] addresses = { new Uri(uri)};
- // Act & Assert
+ // Act and assert
var exception = Assert.Throws(() => builder.SetVerificationEndpointUris(addresses));
Assert.Equal(nameof(addresses), exception.ParamName);
Assert.Contains("One of the specified addresses is not valid.", exception.Message);