52 changed files with 2231 additions and 2042 deletions
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\build\packages.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>net451;netstandard1.4</TargetFrameworks> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<Description>OpenID Connect server components for OpenIddict.</Description> |
|||
<Authors>Kévin Chalet</Authors> |
|||
<PackageTags>aspnetcore;authentication;jwt;openidconnect;openiddict;security</PackageTags> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\OpenIddict.Core\OpenIddict.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="AspNet.Security.OpenIdConnect.Server" Version="$(AspNetContribOpenIdServerVersion)" /> |
|||
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" Version="$(AspNetCoreVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\build\packages.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<Description>Default base stores for OpenIddict.</Description> |
|||
<Authors>Kévin Chalet</Authors> |
|||
<PackageTags>aspnetcore;authentication;jwt;openidconnect;openiddict;security</PackageTags> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\OpenIddict.Core\OpenIddict.Core.csproj" /> |
|||
<ProjectReference Include="..\OpenIddict.Models\OpenIddict.Models.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
File diff suppressed because it is too large
@ -0,0 +1,41 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\build\tests.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netcoreapp1.0;net452</TargetFrameworks> |
|||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp1.0</TargetFrameworks> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Certificate.pfx" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\OpenIddict\OpenIddict.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="AspNet.Security.OpenIdConnect.Client" Version="$(AspNetContribOpenIdServerVersion)" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Facebook" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(AspNetCoreVersion)" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" /> |
|||
<PackageReference Include="Moq" Version="$(MoqVersion)" /> |
|||
<PackageReference Include="xunit" Version="$(XunitVersion)" /> |
|||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
|||
</ItemGroup> |
|||
|
|||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' "> |
|||
<DefineConstants>$(DefineConstants);SUPPORTS_ECDSA</DefineConstants> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,911 @@ |
|||
/* |
|||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|||
* See https://github.com/openiddict/openiddict-core for more information concerning
|
|||
* the license and the contributors participating to this project. |
|||
*/ |
|||
|
|||
using System; |
|||
using System.IdentityModel.Tokens.Jwt; |
|||
using System.Reflection; |
|||
using AspNet.Security.OpenIdConnect.Primitives; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Builder.Internal; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Moq; |
|||
using OpenIddict.Models; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Tests |
|||
{ |
|||
public class OpenIddictExtensionsTests |
|||
{ |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenServicesAreNotRegistered() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("The OpenIddict services cannot be resolved from the dependency injection container. " + |
|||
"Make sure 'services.AddOpenIddict()' is correctly called from 'ConfigureServices()'.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenNoFlowIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOpenIddict(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("At least one OAuth2/OpenID Connect flow must be enabled.", exception.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.Implicit)] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenAuthorizationEndpointIsDisabled(string flow) |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.Configure(options => options.GrantTypes.Add(flow)) |
|||
.Configure(options => options.AuthorizationEndpointPath = PathString.Empty); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("The authorization endpoint must be enabled to use " + |
|||
"the authorization code and implicit flows.", exception.Message); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.ClientCredentials)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.Password)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.RefreshToken)] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenTokenEndpointIsDisabled(string flow) |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.Configure(options => options.GrantTypes.Add(flow)) |
|||
.Configure(options => options.TokenEndpointPath = PathString.Empty); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("The token endpoint must be enabled to use the authorization code, " + |
|||
"client credentials, password and refresh token flows.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenTokenRevocationIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.EnableRevocationEndpoint("/connect/revocation") |
|||
.AllowImplicitFlow() |
|||
.DisableTokenRevocation(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("The revocation endpoint cannot be enabled when token revocation is disabled.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenUsingReferenceTokensWithTokenRevocationDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddDataProtection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.AllowImplicitFlow() |
|||
.DisableTokenRevocation() |
|||
.UseReferenceTokens(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("Reference tokens cannot be used when disabling token revocation.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenUsingReferenceTokensIfAnAccessTokenHandlerIsSet() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddDataProtection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.AllowImplicitFlow() |
|||
.UseReferenceTokens() |
|||
.UseJsonWebTokens(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("Reference tokens cannot be used when configuring JWT as the access token format.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenUsingSlidingExpirationWithoutRollingTokensAndWithTokenRevocationDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddDataProtection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.AllowImplicitFlow() |
|||
.DisableTokenRevocation(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("Sliding expiration must be disabled when turning off " + |
|||
"token revocation if rolling tokens are not used.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_ThrowsAnExceptionWhenNoSigningKeyIsRegisteredIfTheImplicitFlowIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableAuthorizationEndpoint("/connect/authorize") |
|||
.AllowImplicitFlow(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("At least one asymmetric signing key must be registered when enabling the implicit flow. " + |
|||
"Consider registering a X.509 certificate using 'services.AddOpenIddict().AddSigningCertificate()' " + |
|||
"or call 'services.AddOpenIddict().AddEphemeralSigningKey()' to use an ephemeral key.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Configure_OptionsAreCorrectlyAmended() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.Configure(configuration => configuration.Description.DisplayName = "OpenIddict"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("OpenIddict", options.Value.Description.DisplayName); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_OpenIdConnectServerMiddlewareIsRegistered() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.AddSigningCertificate( |
|||
assembly: typeof(OpenIddictProviderTests).GetTypeInfo().Assembly, |
|||
resource: "OpenIddict.Server.Tests.Certificate.pfx", |
|||
password: "OpenIddict") |
|||
.AllowImplicitFlow() |
|||
.EnableAuthorizationEndpoint("/connect/authorize"); |
|||
|
|||
var builder = new Mock<IApplicationBuilder>(); |
|||
builder.SetupGet(mock => mock.ApplicationServices) |
|||
.Returns(services.BuildServiceProvider()); |
|||
|
|||
// Act
|
|||
builder.Object.UseOpenIddict(); |
|||
|
|||
// Assert
|
|||
builder.Verify(mock => mock.Use(It.IsAny<Func<RequestDelegate, RequestDelegate>>()), Times.Once()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddEphemeralSigningKey_SigningKeyIsCorrectlyAdded() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AddEphemeralSigningKey(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(1, options.Value.SigningCredentials.Count); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(SecurityAlgorithms.RsaSha256Signature)] |
|||
[InlineData(SecurityAlgorithms.RsaSha384Signature)] |
|||
[InlineData(SecurityAlgorithms.RsaSha512Signature)] |
|||
#if SUPPORTS_ECDSA
|
|||
[InlineData(SecurityAlgorithms.EcdsaSha256Signature)] |
|||
[InlineData(SecurityAlgorithms.EcdsaSha384Signature)] |
|||
[InlineData(SecurityAlgorithms.EcdsaSha512Signature)] |
|||
#endif
|
|||
public void AddEphemeralSigningKey_SigningCredentialsUseSpecifiedAlgorithm(string algorithm) |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AddEphemeralSigningKey(algorithm); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
var credentials = options.Value.SigningCredentials[0]; |
|||
|
|||
// Assert
|
|||
Assert.Equal(algorithm, credentials.Algorithm); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(SecurityAlgorithms.HmacSha256Signature)] |
|||
[InlineData(SecurityAlgorithms.RsaSha256Signature)] |
|||
#if SUPPORTS_ECDSA
|
|||
[InlineData(SecurityAlgorithms.EcdsaSha256Signature)] |
|||
[InlineData(SecurityAlgorithms.EcdsaSha384Signature)] |
|||
[InlineData(SecurityAlgorithms.EcdsaSha512Signature)] |
|||
#endif
|
|||
public void AddSigningKey_SigningKeyIsCorrectlyAdded(string algorithm) |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
var factory = Mock.Of<CryptoProviderFactory>(mock => |
|||
mock.IsSupportedAlgorithm(algorithm, It.IsAny<SecurityKey>())); |
|||
|
|||
var key = Mock.Of<SecurityKey>(mock => mock.CryptoProviderFactory == factory); |
|||
|
|||
// Act
|
|||
builder.AddSigningKey(key); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Same(key, options.Value.SigningCredentials[0].Key); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddSigningCertificate_SigningKeyIsCorrectlyAdded() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AddSigningCertificate( |
|||
assembly: typeof(OpenIddictExtensionsTests).GetTypeInfo().Assembly, |
|||
resource: "OpenIddict.Server.Tests.Certificate.pfx", |
|||
password: "OpenIddict"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.IsType(typeof(X509SecurityKey), options.Value.SigningCredentials[0].Key); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowAuthorizationCodeFlow_CodeFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowAuthorizationCodeFlow(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode, options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowClientCredentialsFlow_ClientCredentialsFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowClientCredentialsFlow(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(OpenIdConnectConstants.GrantTypes.ClientCredentials, options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowCustomFlow_CustomFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowCustomFlow("urn:ietf:params:oauth:grant-type:custom_grant"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains("urn:ietf:params:oauth:grant-type:custom_grant", options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowImplicitFlow_ImplicitFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowImplicitFlow(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(OpenIdConnectConstants.GrantTypes.Implicit, options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowPasswordFlow_PasswordFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowPasswordFlow(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(OpenIdConnectConstants.GrantTypes.Password, options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AllowRefreshTokenFlow_RefreshTokenFlowIsAddedToGrantTypes() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AllowRefreshTokenFlow(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken, options.Value.GrantTypes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DisableConfigurationEndpoint_ConfigurationEndpointIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.DisableConfigurationEndpoint(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(PathString.Empty, options.Value.ConfigurationEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DisableCryptographyEndpoint_CryptographyEndpointIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.DisableCryptographyEndpoint(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(PathString.Empty, options.Value.CryptographyEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DisableSlidingExpiration_SlidingExpirationIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.DisableSlidingExpiration(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.False(options.Value.UseSlidingExpiration); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DisableTokenRevocation_TokenRevocationIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.DisableTokenRevocation(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.True(options.Value.DisableTokenRevocation); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableAuthorizationEndpoint_AuthorizationEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableAuthorizationEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.AuthorizationEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableIntrospectionEndpoint_IntrospectionEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableIntrospectionEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.IntrospectionEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableLogoutEndpoint_LogoutEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableLogoutEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.LogoutEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableRequestCaching_RequestCachingIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableRequestCaching(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.True(options.Value.EnableRequestCaching); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableRevocationEndpoint_RevocationEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableRevocationEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.RevocationEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableScopeValidation_ScopeValidationIsDisabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableScopeValidation(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.True(options.Value.EnableScopeValidation); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableTokenEndpoint_TokenEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableTokenEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.TokenEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void EnableUserinfoEndpoint_UserinfoEndpointIsEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.EnableUserinfoEndpoint("/endpoint-path"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal("/endpoint-path", options.Value.UserinfoEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RequireClientIdentification_ClientIdentificationIsEnforced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.RequireClientIdentification(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.True(options.Value.RequireClientIdentification); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetAccessTokenLifetime_DefaultAccessTokenLifetimeIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.SetAccessTokenLifetime(TimeSpan.FromMinutes(42)); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(TimeSpan.FromMinutes(42), options.Value.AccessTokenLifetime); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetAuthorizationCodeLifetime_DefaultAuthorizationCodeLifetimeIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.SetAuthorizationCodeLifetime(TimeSpan.FromMinutes(42)); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(TimeSpan.FromMinutes(42), options.Value.AuthorizationCodeLifetime); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetIdentityTokenLifetime_DefaultIdentityTokenLifetimeIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.SetIdentityTokenLifetime(TimeSpan.FromMinutes(42)); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(TimeSpan.FromMinutes(42), options.Value.IdentityTokenLifetime); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetRefreshTokenLifetime_DefaultRefreshTokenLifetimeIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.SetRefreshTokenLifetime(TimeSpan.FromMinutes(42)); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(TimeSpan.FromMinutes(42), options.Value.RefreshTokenLifetime); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SetIssuer_AddressIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.SetIssuer(new Uri("http://www.fabrikam.com/")); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Equal(new Uri("http://www.fabrikam.com/"), options.Value.Issuer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RegisterClaims_ClaimsAreAdded() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.RegisterClaims("custom_claim_1", "custom_claim_2"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains("custom_claim_1", options.Value.Claims); |
|||
Assert.Contains("custom_claim_2", options.Value.Claims); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RegisterScopes_ScopesAreAdded() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.RegisterScopes("custom_scope_1", "custom_scope_2"); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains("custom_scope_1", options.Value.Scopes); |
|||
Assert.Contains("custom_scope_2", options.Value.Scopes); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseDataProtectionProvider_DefaultProviderIsReplaced() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.UseDataProtectionProvider(new EphemeralDataProtectionProvider()); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.IsType(typeof(EphemeralDataProtectionProvider), options.Value.DataProtectionProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseJsonWebTokens_AccessTokenHandlerIsCorrectlySet() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.UseJsonWebTokens(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.IsType<JwtSecurityTokenHandler>(options.Value.AccessTokenHandler); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseReferenceTokens_ReferenceTokensAreEnabled() |
|||
{ |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = CreateBuilder(services); |
|||
|
|||
// Act
|
|||
builder.UseReferenceTokens(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.True(options.Value.UseReferenceTokens); |
|||
} |
|||
|
|||
private static OpenIddictBuilder CreateBuilder(IServiceCollection services) |
|||
=> new OpenIddictBuilder(services) |
|||
{ |
|||
ApplicationType = typeof(OpenIddictApplication), |
|||
AuthorizationType = typeof(OpenIddictAuthorization), |
|||
ScopeType = typeof(OpenIddictScope), |
|||
TokenType = typeof(OpenIddictToken) |
|||
}; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue