Browse Source

Prevent enabling the device authorization flow when token storage is disabled (unless the degraded mode is used)

pull/1626/head
Kévin Chalet 3 years ago
parent
commit
773594231e
  1. 3
      src/OpenIddict.Abstractions/OpenIddictResources.resx
  2. 11
      src/OpenIddict.Server/OpenIddictServerConfiguration.cs
  3. 13
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs
  4. 28
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs
  5. 10
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs

3
src/OpenIddict.Abstractions/OpenIddictResources.resx

@ -1393,6 +1393,9 @@ Consider registering a certificate using 'services.AddOpenIddict().AddClient().A
<data name="ID0366" xml:space="preserve">
<value>The '{0}' parameter cannot be null or empty.</value>
</data>
<data name="ID0367" xml:space="preserve">
<value>The device authorization flow cannot be enabled when token storage is disabled (unless the degraded mode is used).</value>
</data>
<data name="ID2000" xml:space="preserve">
<value>The security token is missing.</value>
</data>

11
src/OpenIddict.Server/OpenIddictServerConfiguration.cs

@ -138,6 +138,13 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions<OpenId
throw new InvalidOperationException(SR.GetResourceString(SR.ID0083));
}
// Prevent the device authorization flow from being used if token storage is disabled, unless the degraded
// mode has been enabled (in this case, additional checks will be enforced later to require custom handlers).
if (options.DisableTokenStorage && !options.EnableDegradedMode && options.GrantTypes.Contains(GrantTypes.DeviceCode))
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0367));
}
if (options.EncryptionCredentials.Count is 0)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID0085));
@ -149,14 +156,14 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions<OpenId
}
// If all the registered encryption credentials are backed by a X.509 certificate, at least one of them must be valid.
if (options.EncryptionCredentials.TrueForAll(credentials => 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));

13
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode));
options.DisableAuthorizationStorage();
options.DisableTokenStorage();
options.DisableSlidingRefreshTokenExpiration();

28
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<OpenIddictTokenDescriptor>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny<CancellationToken>()))
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56");
mock.Setup(manager => manager.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
}));
options.RegisterScopes("registered_scope");
options.SetRevocationEndpointUris(Array.Empty<Uri>());
options.DisableAuthorizationStorage();
options.DisableTokenStorage();
options.DisableSlidingRefreshTokenExpiration();
options.AddEventHandler<HandleDeviceRequestContext>(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<OpenIddictTokenDescriptor>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
mock.Setup(manager => manager.GetIdAsync(token, It.IsAny<CancellationToken>()))
.ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56");
mock.Setup(manager => manager.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
}));
options.RegisterScopes("scope_registered_in_options");
options.SetRevocationEndpointUris(Array.Empty<Uri>());
options.DisableAuthorizationStorage();
options.DisableTokenStorage();
options.DisableSlidingRefreshTokenExpiration();
options.Services.AddSingleton(manager);

10
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
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<Uri>());
options.SetRevocationEndpointUris(Array.Empty<Uri>());
options.Configure(options => options.GrantTypes.Remove(GrantTypes.DeviceCode));
options.DisableTokenStorage();
options.DisableSlidingRefreshTokenExpiration();
});

Loading…
Cancel
Save