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);