Browse Source

Automatically disable the incompatible options when enabling the degraded mode

pull/1043/head
Kévin Chalet 6 years ago
parent
commit
5f164309cd
  1. 6
      src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx
  2. 24
      src/OpenIddict.Server/OpenIddictServerConfiguration.cs
  3. 60
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

6
src/OpenIddict.Abstractions/Resources/OpenIddictResources.resx

@ -396,12 +396,6 @@ Consider using 'options.AddSigningCredentials(SigningCredentials)' instead.</val
<data name="ID1079" xml:space="preserve"> <data name="ID1079" xml:space="preserve">
<value>The verification endpoint must be enabled to use the device flow.</value> <value>The verification endpoint must be enabled to use the device flow.</value>
</data> </data>
<data name="ID1080" xml:space="preserve">
<value>The device and verification endpoints cannot be enabled when token storage is disabled.</value>
</data>
<data name="ID1081" xml:space="preserve">
<value>The revocation endpoint cannot be enabled when token storage is disabled.</value>
</data>
<data name="ID1082" xml:space="preserve"> <data name="ID1082" xml:space="preserve">
<value>Reference tokens cannot be used when disabling token storage.</value> <value>Reference tokens cannot be used when disabling token storage.</value>
</data> </data>

24
src/OpenIddict.Server/OpenIddictServerConfiguration.cs

@ -34,6 +34,20 @@ namespace OpenIddict.Server
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
if (options.EnableDegradedMode)
{
// Explicitly disable all the features that are implicitly excluded when the degraded mode is active.
options.DisableAuthorizationStorage = options.DisableTokenStorage = true;
options.IgnoreEndpointPermissions = options.IgnoreGrantTypePermissions = options.IgnoreScopePermissions = true;
options.UseReferenceAccessTokens = options.UseReferenceRefreshTokens = false;
// When the degraded mode is enabled (and the token storage disabled), OpenIddict is not able to dynamically
// update the expiration date of a token. As such, either rolling tokens MUST be enabled or sliding token
// expiration MUST be disabled to always issue new refresh tokens with the same fixed expiration date.
// By default, OpenIddict will automatically force the rolling tokens option when using the degraded mode.
options.UseRollingRefreshTokens |= !options.UseRollingRefreshTokens && !options.DisableSlidingRefreshTokenExpiration;
}
if (options.JsonWebTokenHandler == null) if (options.JsonWebTokenHandler == null)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1074)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1074));
@ -78,16 +92,6 @@ namespace OpenIddict.Server
if (options.DisableTokenStorage) if (options.DisableTokenStorage)
{ {
if (options.DeviceEndpointUris.Count != 0 || options.VerificationEndpointUris.Count != 0)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1080));
}
if (options.RevocationEndpointUris.Count != 0)
{
throw new InvalidOperationException(SR.GetResourceString(SR.ID1081));
}
if (options.UseReferenceAccessTokens || options.UseReferenceRefreshTokens) if (options.UseReferenceAccessTokens || options.UseReferenceRefreshTokens)
{ {
throw new InvalidOperationException(SR.GetResourceString(SR.ID1082)); throw new InvalidOperationException(SR.GetResourceString(SR.ID1082));

60
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs

@ -2192,7 +2192,7 @@ namespace OpenIddict.Server.IntegrationTests
} }
[Fact] [Fact]
public async Task ProcessSignIn_NoRefreshTokenIsReturnedForRefreshTokenGrantRequests() public async Task ProcessSignIn_ARefreshTokenIsReturnedForRefreshTokenGrantRequests()
{ {
// Arrange // Arrange
await using var server = await CreateServerAsync(options => await using var server = await CreateServerAsync(options =>
@ -2221,60 +2221,7 @@ namespace OpenIddict.Server.IntegrationTests
{ {
builder.UseInlineHandler(context => builder.UseInlineHandler(context =>
{ {
Assert.False(context.IncludeRefreshToken); Assert.True(context.IncludeRefreshToken);
return default;
});
builder.SetOrder(EvaluateReturnedTokens.Descriptor.Order + 500);
});
});
await using var client = await server.CreateClientAsync();
// Act
var response = await client.PostAsync("/connect/token", new OpenIddictRequest
{
GrantType = GrantTypes.RefreshToken,
RefreshToken = "8xLOxBtZp8"
});
// Assert
Assert.Null(response.RefreshToken);
}
[Fact]
public async Task ProcessSignIn_NoRefreshTokenIsReturnedWhenSlidingExpirationIsDisabled()
{
// Arrange
await using var server = await CreateServerAsync(options =>
{
options.EnableDegradedMode();
options.DisableSlidingRefreshTokenExpiration();
options.AddEventHandler<ProcessAuthenticationContext>(builder =>
{
builder.UseInlineHandler(context =>
{
Assert.Equal("8xLOxBtZp8", context.Token);
Assert.Equal(TokenTypeHints.RefreshToken, context.TokenType);
context.Principal = new ClaimsPrincipal(new ClaimsIdentity("Bearer"))
.SetTokenType(TokenTypeHints.RefreshToken)
.SetScopes(Scopes.OfflineAccess)
.SetClaim(Claims.Subject, "Bob le Bricoleur");
return default;
});
builder.SetOrder(ValidateIdentityModelToken.Descriptor.Order - 500);
});
options.AddEventHandler<ProcessSignInContext>(builder =>
{
builder.UseInlineHandler(context =>
{
Assert.False(context.IncludeRefreshToken);
return default; return default;
}); });
@ -2293,7 +2240,7 @@ namespace OpenIddict.Server.IntegrationTests
}); });
// Assert // Assert
Assert.Null(response.RefreshToken); Assert.NotNull(response.RefreshToken);
} }
[Fact] [Fact]
@ -3003,6 +2950,7 @@ namespace OpenIddict.Server.IntegrationTests
await using var server = await CreateServerAsync(options => await using var server = await CreateServerAsync(options =>
{ {
options.EnableDegradedMode(); options.EnableDegradedMode();
options.DisableSlidingRefreshTokenExpiration();
options.AddEventHandler<ProcessAuthenticationContext>(builder => options.AddEventHandler<ProcessAuthenticationContext>(builder =>
{ {

Loading…
Cancel
Save