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