diff --git a/src/OpenIddict.Abstractions/OpenIddictResources.resx b/src/OpenIddict.Abstractions/OpenIddictResources.resx index a4a1d0e6..1cfb795b 100644 --- a/src/OpenIddict.Abstractions/OpenIddictResources.resx +++ b/src/OpenIddict.Abstractions/OpenIddictResources.resx @@ -1393,6 +1393,9 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A The '{0}' parameter cannot be null or empty. + + The device authorization flow cannot be enabled when token storage is disabled (unless the degraded mode is used). + The security token is missing. diff --git a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs index 55a6f477..1d8d7327 100644 --- a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs +++ b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs @@ -138,6 +138,13 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions credentials.Key is X509SecurityKey x509SecurityKey && + if (options.EncryptionCredentials.TrueForAll(static credentials => credentials.Key is X509SecurityKey x509SecurityKey && (x509SecurityKey.Certificate.NotBefore > DateTime.Now || x509SecurityKey.Certificate.NotAfter < DateTime.Now))) { throw new InvalidOperationException(SR.GetResourceString(SR.ID0087)); } // If all the registered signing credentials are backed by a X.509 certificate, at least one of them must be valid. - if (options.SigningCredentials.TrueForAll(credentials => credentials.Key is X509SecurityKey x509SecurityKey && + if (options.SigningCredentials.TrueForAll(static credentials => credentials.Key is X509SecurityKey x509SecurityKey && (x509SecurityKey.Certificate.NotBefore > DateTime.Now || x509SecurityKey.Certificate.NotAfter < DateTime.Now))) { throw new InvalidOperationException(SR.GetResourceString(SR.ID0088)); diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs index d698c31d..05f33f57 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs @@ -832,7 +832,9 @@ public abstract partial class OpenIddictServerIntegrationTests var scope = new OpenIddictScope(); options.RegisterScopes("scope_registered_in_options"); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1445,6 +1447,9 @@ public abstract partial class OpenIddictServerIntegrationTests { options.Services.AddSingleton(manager); + options.SetDeviceEndpointUris(Array.Empty()); + options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableAuthorizationStorage(); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1695,7 +1700,9 @@ public abstract partial class OpenIddictServerIntegrationTests await using var server = await CreateServerAsync(options => { + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableAuthorizationStorage(); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1753,7 +1760,9 @@ public abstract partial class OpenIddictServerIntegrationTests await using var server = await CreateServerAsync(options => { + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableAuthorizationStorage(); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1811,7 +1820,9 @@ public abstract partial class OpenIddictServerIntegrationTests await using var server = await CreateServerAsync(options => { + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableAuthorizationStorage(); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1935,7 +1946,9 @@ public abstract partial class OpenIddictServerIntegrationTests await using var server = await CreateServerAsync(options => { + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableAuthorizationStorage(); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs index b02fdbc6..c7b58342 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs @@ -230,6 +230,7 @@ public abstract partial class OpenIddictServerIntegrationTests { // Arrange var application = new OpenIddictApplication(); + var token = new OpenIddictToken(); await using var server = await CreateServerAsync(options => { @@ -242,10 +243,21 @@ public abstract partial class OpenIddictServerIntegrationTests .ReturnsAsync(true); })); + options.Services.AddSingleton(CreateTokenManager(mock => + { + mock.Setup(manager => manager.CreateAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(token); + + 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.RegisterScopes("registered_scope"); options.SetRevocationEndpointUris(Array.Empty()); options.DisableAuthorizationStorage(); - options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); options.AddEventHandler(builder => @@ -280,6 +292,7 @@ public abstract partial class OpenIddictServerIntegrationTests // Arrange var application = new OpenIddictApplication(); var scope = new OpenIddictScope(); + var token = new OpenIddictToken(); var manager = CreateScopeManager(mock => { @@ -303,10 +316,21 @@ public abstract partial class OpenIddictServerIntegrationTests .ReturnsAsync(true); })); + options.Services.AddSingleton(CreateTokenManager(mock => + { + mock.Setup(manager => manager.CreateAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(token); + + 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.RegisterScopes("scope_registered_in_options"); options.SetRevocationEndpointUris(Array.Empty()); options.DisableAuthorizationStorage(); - options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); options.Services.AddSingleton(manager); diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs index 0f34537c..afedea8e 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs @@ -1335,7 +1335,9 @@ public abstract partial class OpenIddictServerIntegrationTests await using var server = await CreateServerAsync(options => { options.RegisterScopes("scope_registered_in_options"); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); @@ -1909,7 +1911,9 @@ public abstract partial class OpenIddictServerIntegrationTests options.Services.AddSingleton(manager); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); }); @@ -1977,7 +1981,9 @@ public abstract partial class OpenIddictServerIntegrationTests options.Services.AddSingleton(manager); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); }); @@ -2153,7 +2159,9 @@ public abstract partial class OpenIddictServerIntegrationTests .ReturnsAsync(true); })); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); }); @@ -2206,7 +2214,9 @@ public abstract partial class OpenIddictServerIntegrationTests return default; })); + options.SetDeviceEndpointUris(Array.Empty()); options.SetRevocationEndpointUris(Array.Empty()); + options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode)); options.DisableTokenStorage(); options.DisableSlidingRefreshTokenExpiration(); });