31 changed files with 5277 additions and 223 deletions
File diff suppressed because it is too large
@ -0,0 +1,471 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.IdentityModel.Protocols; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Client.Tests; |
|||
|
|||
public class OpenIddictClientConfigurationTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_ThrowsAnExceptionForNullProvider() |
|||
{ |
|||
// Arrange
|
|||
var provider = (IServiceProvider) null!; |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictClientConfiguration(provider)); |
|||
Assert.Equal("provider", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.PostConfigure(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_SetsTimeProviderToSystemWhenNotRegistered() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictClientOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(TimeProvider.System, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_UsesRegisteredTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var timeProvider = new FakeTimeProvider(); |
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(timeProvider); |
|||
|
|||
var configuration = new OpenIddictClientConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictClientOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(timeProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_DoesNotOverrideExplicitlySetTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var explicitProvider = new FakeTimeProvider(); |
|||
var registeredProvider = new FakeTimeProvider(); |
|||
|
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(registeredProvider); |
|||
|
|||
var configuration = new OpenIddictClientConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictClientOptions { TimeProvider = explicitProvider }; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(explicitProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_ComputesDefaultRegistrationIdentifierAndClientType() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
var registration = new OpenIddictClientRegistration |
|||
{ |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ClientSecret = "secret", |
|||
Configuration = new OpenIddictConfiguration() |
|||
}; |
|||
|
|||
var options = new OpenIddictClientOptions(); |
|||
options.Registrations.Add(registration); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.False(string.IsNullOrEmpty(registration.RegistrationId)); |
|||
Assert.Equal(ClientTypes.Confidential, registration.ClientType); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_AssignsPublicClientTypeWhenNoSecretOrSigningCredentialsAreConfigured() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
var registration = new OpenIddictClientRegistration |
|||
{ |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
Configuration = new OpenIddictConfiguration() |
|||
}; |
|||
|
|||
var options = new OpenIddictClientOptions(); |
|||
options.Registrations.Add(registration); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Equal(ClientTypes.Public, registration.ClientType); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_AddsRedirectionUrisFromRegistrations() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
var options = new OpenIddictClientOptions(); |
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RedirectUri = new Uri("https://www.contoso.com/callback") |
|||
}); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
PostLogoutRedirectUri = new Uri("https://www.contoso.com/logout-callback") |
|||
}); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(new Uri("https://www.contoso.com/callback"), options.RedirectionEndpointUris); |
|||
Assert.Contains(new Uri("https://www.contoso.com/logout-callback"), options.PostLogoutRedirectionEndpointUris); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.Validate(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.JsonWebTokenHandler = null!; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRegistrationIdentifierContainsSeparator() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "invalid\u001eidentifier", |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0455), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRegistrationIdentifierIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0521), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIssuerIsInvalid() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("/relative", UriKind.Relative), |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIssuerContainsQueryOrFragment() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("https://www.contoso.com/?query=parameter#fragment"), |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRegistrationConfigurationIssuerDoesNotMatchRegistrationIssuer() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
Configuration = new OpenIddictConfiguration { Issuer = new Uri("https://www.fabrikam.com/") }, |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0395), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenConfigurationManagerIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("https://www.contoso.com/") |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0522), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNonStaticConfigurationManagerIsUsedWithoutRequiredHandlers() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ConfigurationManager = Mock.Of<IConfigurationManager<OpenIddictConfiguration>>() |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0313), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNoFlowIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictClientOptions(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenEndpointUrisAreNotUnique() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
var uri = new Uri("https://www.contoso.com/callback"); |
|||
options.RedirectionEndpointUris.Add(uri); |
|||
options.PostLogoutRedirectionEndpointUris.Add(uri); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRedirectionEndpointIsMissingForAuthorizationCodeGrant() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.GrantTypes.Add(GrantTypes.AuthorizationCode); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0356), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenStateTokenCredentialsAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.RedirectionEndpointUris.Add(new Uri("https://www.contoso.com/callback")); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0357), result.Failures!); |
|||
Assert.Contains(SR.GetResourceString(SR.ID0358), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenResponseTypeIsInconsistentWithEnabledGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.ResponseTypes.Add(ResponseTypes.Code); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.FormatID0281(ResponseTypes.Code), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_SucceedsForConsistentMinimalConfiguration() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "contoso", |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()) |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.True(result.Succeeded); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRegistrationIdentifiersAreDuplicated() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictClientConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
var manager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "duplicate", |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
ConfigurationManager = manager |
|||
}); |
|||
|
|||
options.Registrations.Add(new OpenIddictClientRegistration |
|||
{ |
|||
RegistrationId = "DUPLICATE", |
|||
Issuer = new Uri("https://www.fabrikam.com/"), |
|||
ConfigurationManager = manager |
|||
}); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0347), result.Failures!); |
|||
} |
|||
|
|||
private static OpenIddictClientOptions CreateBaseOptions() |
|||
{ |
|||
var options = new OpenIddictClientOptions |
|||
{ |
|||
TimeProvider = TimeProvider.System |
|||
}; |
|||
|
|||
options.GrantTypes.Add(GrantTypes.ClientCredentials); |
|||
|
|||
return options; |
|||
} |
|||
|
|||
private sealed class FakeTimeProvider : TimeProvider; |
|||
} |
|||
@ -0,0 +1,555 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Server.Tests; |
|||
|
|||
public class OpenIddictServerConfigurationTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_ThrowsAnExceptionForNullProvider() |
|||
{ |
|||
// Arrange
|
|||
var provider = (IServiceProvider) null!; |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictServerConfiguration(provider)); |
|||
Assert.Equal("provider", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.PostConfigure(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_SetsTimeProviderToSystemWhenNotRegistered() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictServerOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(TimeProvider.System, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_UsesRegisteredTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var timeProvider = new FakeTimeProvider(); |
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(timeProvider); |
|||
|
|||
var configuration = new OpenIddictServerConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictServerOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(timeProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_DoesNotOverrideExplicitlySetTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var explicitProvider = new FakeTimeProvider(); |
|||
var registeredProvider = new FakeTimeProvider(); |
|||
|
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(registeredProvider); |
|||
|
|||
var configuration = new OpenIddictServerConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictServerOptions { TimeProvider = explicitProvider }; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(explicitProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_DisablesFeaturesWhenDegradedModeIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictServerOptions |
|||
{ |
|||
EnableDegradedMode = true, |
|||
EnableAuthorizationRequestCaching = true, |
|||
EnableEndSessionRequestCaching = true, |
|||
UseReferenceAccessTokens = true, |
|||
UseReferenceRefreshTokens = true |
|||
}; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.True(options.DisableAuthorizationStorage); |
|||
Assert.True(options.DisableTokenStorage); |
|||
Assert.True(options.DisableRollingRefreshTokens); |
|||
Assert.False(options.EnableAuthorizationRequestCaching); |
|||
Assert.False(options.EnableEndSessionRequestCaching); |
|||
Assert.True(options.IgnoreEndpointPermissions); |
|||
Assert.True(options.IgnoreGrantTypePermissions); |
|||
Assert.True(options.IgnoreResponseTypePermissions); |
|||
Assert.True(options.IgnoreScopePermissions); |
|||
Assert.False(options.UseReferenceAccessTokens); |
|||
Assert.False(options.UseReferenceRefreshTokens); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_DisablesUserCodeFormattingWhenTokenStorageIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictServerOptions |
|||
{ |
|||
DisableTokenStorage = true |
|||
}; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.True(options.DisableRollingRefreshTokens); |
|||
Assert.Equal(0, options.UserCodeLength); |
|||
Assert.Empty(options.UserCodeCharset); |
|||
Assert.Null(options.UserCodeDisplayFormat); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.Validate(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.JsonWebTokenHandler = null!; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNoFlowIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenEndpointUrisAreNotUnique() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
var uri = new Uri("https://www.contoso.com/connect/shared"); |
|||
options.AuthorizationEndpointUris.Add(uri); |
|||
options.TokenEndpointUris.Add(uri); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenAuthorizationEndpointIsMissingForAuthorizationCodeGrant() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.GrantTypes.Add(GrantTypes.AuthorizationCode); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0077), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenTokenEndpointIsMissingForPasswordGrant() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.GrantTypes.Add(GrantTypes.Password); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0079), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDeviceVerificationEndpointIsMissingForDeviceGrant() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.GrantTypes.Add(GrantTypes.DeviceCode); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0080), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDeviceEndpointIsEnabledWithoutDeviceGrant() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.DeviceAuthorizationEndpointUris.Add(new Uri("https://www.contoso.com/connect/device")); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0084), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNoClientAuthenticationMethodIsEnabledForNonInteractiveEndpoints() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.TokenEndpointUris.Add(new Uri("https://www.contoso.com/connect/token")); |
|||
options.ClientAuthenticationMethods.Clear(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0419), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenPrivateKeyJwtIsEnabledWithoutJwtBearerAssertionType() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ClientAuthenticationMethods.Clear(); |
|||
options.ClientAuthenticationMethods.Add(ClientAuthenticationMethods.PrivateKeyJwt); |
|||
options.ClientAssertionTypes.Clear(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.FormatID0420(ClientAssertionTypes.JwtBearer, ClientAuthenticationMethods.PrivateKeyJwt), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenTlsClientAuthMethodIsEnabledWithoutPolicy() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.ClientAuthenticationMethods.Add(ClientAuthenticationMethods.TlsClientAuth); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0505), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenSelfSignedTlsClientAuthMethodIsEnabledWithoutPolicy() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.ClientAuthenticationMethods.Add(ClientAuthenticationMethods.SelfSignedTlsClientAuth); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0506), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenSubjectTypesAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.SubjectTypes.Clear(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0421), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenReferenceTokensAreEnabledWithDisabledTokenStorage() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.DisableTokenStorage = true; |
|||
options.UseReferenceAccessTokens = true; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0083), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenRequestCachingIsEnabledWithDisabledTokenStorage() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.DisableTokenStorage = true; |
|||
options.EnableAuthorizationRequestCaching = true; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0465), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDeviceGrantIsEnabledWithDisabledTokenStorageOutsideDegradedMode() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.DisableTokenStorage = true; |
|||
options.EnableDegradedMode = false; |
|||
options.GrantTypes.Add(GrantTypes.DeviceCode); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0367), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenTokenExchangeGrantIsEnabledWithoutSubjectTokenTypes() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.GrantTypes.Add(GrantTypes.TokenExchange); |
|||
options.SubjectTokenTypes.Clear(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0486), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDefaultRequestedTokenTypeIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.DefaultRequestedTokenType = string.Empty; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0490), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDefaultRequestedTokenTypeIsNotAllowed() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.RequestedTokenTypes.Clear(); |
|||
options.DefaultRequestedTokenType = TokenTypeIdentifiers.AccessToken; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0492), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenEncryptionCredentialsAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0085), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNoAsymmetricSigningCredentialIsRegistered() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.EncryptionCredentials.Add(new EncryptingCredentials( |
|||
new SymmetricSecurityKey(new byte[32]), |
|||
SecurityAlgorithms.Aes256KW, |
|||
SecurityAlgorithms.Aes256CbcHmacSha512)); |
|||
|
|||
options.SigningCredentials.Add(new SigningCredentials( |
|||
new SymmetricSecurityKey(new byte[32]), |
|||
SecurityAlgorithms.HmacSha256)); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0086), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsInvalid() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.MtlsTokenEndpointAliasUri = new Uri("http://www.contoso.com/connect/token", UriKind.Absolute); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0499), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsConfiguredWithoutEndpoint() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.MtlsTokenEndpointAliasUri = new Uri("https://www.contoso.com/connect/token", UriKind.Absolute); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0510), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsConfiguredWithoutIssuer() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.TokenEndpointUris.Add(new Uri("https://www.contoso.com/connect/token")); |
|||
options.MtlsTokenEndpointAliasUri = new Uri("https://mtls.contoso.com/connect/token", UriKind.Absolute); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0500), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenDegradedModeIsEnabledAndCustomTokenEndpointHandlersAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.EnableDegradedMode = true; |
|||
options.TokenEndpointUris.Add(new Uri("https://www.contoso.com/connect/token")); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0094), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenUserCodeLengthIsTooShort() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.UserCodeLength = 5; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.FormatID0439(6), result.Failures!); |
|||
} |
|||
|
|||
private static OpenIddictServerOptions CreateBaseOptions() |
|||
=> new() |
|||
{ |
|||
TimeProvider = TimeProvider.System |
|||
}; |
|||
|
|||
private sealed class FakeTimeProvider : TimeProvider; |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,372 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.IdentityModel.Protocols; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Moq; |
|||
using Xunit; |
|||
using static OpenIddict.Validation.OpenIddictValidationEvents; |
|||
|
|||
namespace OpenIddict.Validation.Tests; |
|||
|
|||
public class OpenIddictValidationConfigurationTests |
|||
{ |
|||
[Fact] |
|||
public void Constructor_ThrowsAnExceptionForNullProvider() |
|||
{ |
|||
// Arrange
|
|||
var provider = (IServiceProvider) null!; |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictValidationConfiguration(provider)); |
|||
Assert.Equal("provider", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.PostConfigure(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_SetsTimeProviderToSystemWhenNotRegistered() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictValidationOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(TimeProvider.System, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_UsesRegisteredTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var timeProvider = new FakeTimeProvider(); |
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(timeProvider); |
|||
|
|||
var configuration = new OpenIddictValidationConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictValidationOptions(); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(timeProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_DoesNotOverrideExplicitlySetTimeProvider() |
|||
{ |
|||
// Arrange
|
|||
var explicitProvider = new FakeTimeProvider(); |
|||
var registeredProvider = new FakeTimeProvider(); |
|||
|
|||
var services = new ServiceCollection(); |
|||
services.AddSingleton<TimeProvider>(registeredProvider); |
|||
|
|||
var configuration = new OpenIddictValidationConfiguration(services.BuildServiceProvider()); |
|||
var options = new OpenIddictValidationOptions { TimeProvider = explicitProvider }; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Same(explicitProvider, options.TimeProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_CreatesStaticConfigurationManagerFromStaticConfiguration() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictValidationOptions |
|||
{ |
|||
Issuer = new Uri("https://www.contoso.com/"), |
|||
Configuration = new OpenIddictConfiguration() |
|||
}; |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.IsType<StaticConfigurationManager<OpenIddictConfiguration>>(options.ConfigurationManager); |
|||
Assert.Equal(options.Issuer, options.Configuration.Issuer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void PostConfigure_AttachesEncryptionKeysToTokenValidationParameters() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = new OpenIddictValidationOptions(); |
|||
|
|||
var key = new SymmetricSecurityKey(new byte[32]); |
|||
options.EncryptionCredentials.Add(new EncryptingCredentials( |
|||
key, |
|||
SecurityAlgorithms.Aes256KW, |
|||
SecurityAlgorithms.Aes256CbcHmacSha512)); |
|||
|
|||
// Act
|
|||
configuration.PostConfigure(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(key, options.TokenValidationParameters.TokenDecryptionKeys); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ThrowsAnExceptionForNullOptions() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<ArgumentNullException>(() => configuration.Validate(name: null, options: null!)); |
|||
Assert.Equal("options", exception.ParamName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.JsonWebTokenHandler = null!; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNoIssuerOrConfigurationInformationIsProvided() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0128), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIssuerIsInvalid() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Issuer = new Uri("/relative", UriKind.Relative); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIssuerContainsQueryOrFragment() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.Issuer = new Uri("https://www.contoso.com/?query=parameter#fragment"); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenConfigurationIssuerDoesNotMatchOptionsIssuer() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.Configuration = new OpenIddictConfiguration |
|||
{ |
|||
Issuer = new Uri("https://www.fabrikam.com/") |
|||
}; |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0394), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenConfigurationManagerIsMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0523), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenNonStaticConfigurationManagerIsUsedWithoutRequiredHandlers() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.ConfigurationManager = Mock.Of<IConfigurationManager<OpenIddictConfiguration>>(); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0135), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIntrospectionHandlersAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ValidationType = OpenIddictValidationType.Introspection; |
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.ConfigurationEndpoint = new Uri("https://www.contoso.com/.well-known/openid-configuration"); |
|||
options.ClientId = "client_id"; |
|||
options.ClientSecret = "client_secret"; |
|||
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0129), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIntrospectionIssuerAndConfigurationEndpointAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ValidationType = OpenIddictValidationType.Introspection; |
|||
options.ClientId = "client_id"; |
|||
options.ClientSecret = "client_secret"; |
|||
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
options.Handlers.Add(OpenIddictValidationHandlerDescriptor.CreateBuilder<ApplyIntrospectionRequestContext>() |
|||
.UseSingletonHandler<CustomIntrospectionHandler>().Build()); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0130), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenIntrospectionClientCredentialsAreMissing() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ValidationType = OpenIddictValidationType.Introspection; |
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.ConfigurationEndpoint = new Uri("https://www.contoso.com/.well-known/openid-configuration"); |
|||
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0131), result.Failures!); |
|||
Assert.Contains(SR.GetResourceString(SR.ID0132), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_ReturnsAnErrorWhenAuthorizationOrTokenEntryValidationIsEnabledInIntrospectionMode() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ValidationType = OpenIddictValidationType.Introspection; |
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.ConfigurationEndpoint = new Uri("https://www.contoso.com/.well-known/openid-configuration"); |
|||
options.ClientId = "client_id"; |
|||
options.ClientSecret = "client_secret"; |
|||
options.EnableAuthorizationEntryValidation = true; |
|||
options.EnableTokenEntryValidation = true; |
|||
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.Contains(SR.GetResourceString(SR.ID0133), result.Failures!); |
|||
Assert.Contains(SR.GetResourceString(SR.ID0134), result.Failures!); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Validate_SucceedsForValidIntrospectionConfigurationUsingClientAssertion() |
|||
{ |
|||
// Arrange
|
|||
var configuration = new OpenIddictValidationConfiguration(new ServiceCollection().BuildServiceProvider()); |
|||
var options = CreateBaseOptions(); |
|||
|
|||
options.ValidationType = OpenIddictValidationType.Introspection; |
|||
options.Issuer = new Uri("https://www.contoso.com/"); |
|||
options.ConfigurationEndpoint = new Uri("https://www.contoso.com/.well-known/openid-configuration"); |
|||
options.ClientId = "client_id"; |
|||
options.ConfigurationManager = new StaticConfigurationManager<OpenIddictConfiguration>(new OpenIddictConfiguration()); |
|||
options.SigningCredentials.Add(new SigningCredentials( |
|||
new SymmetricSecurityKey(new byte[32]), |
|||
SecurityAlgorithms.HmacSha256)); |
|||
|
|||
options.Handlers.Add(OpenIddictValidationHandlerDescriptor.CreateBuilder<ApplyIntrospectionRequestContext>() |
|||
.UseSingletonHandler<CustomIntrospectionHandler>().Build()); |
|||
|
|||
// Act
|
|||
var result = configuration.Validate(name: null, options); |
|||
|
|||
// Assert
|
|||
Assert.True(result.Succeeded); |
|||
} |
|||
|
|||
private static OpenIddictValidationOptions CreateBaseOptions() |
|||
=> new() |
|||
{ |
|||
TimeProvider = TimeProvider.System |
|||
}; |
|||
|
|||
private sealed class CustomIntrospectionHandler : IOpenIddictValidationHandler<ApplyIntrospectionRequestContext> |
|||
{ |
|||
public ValueTask HandleAsync(ApplyIntrospectionRequestContext context) => ValueTask.CompletedTask; |
|||
} |
|||
|
|||
private sealed class FakeTimeProvider : TimeProvider; |
|||
} |
|||
Loading…
Reference in new issue