69 changed files with 2936 additions and 2190 deletions
@ -1,57 +0,0 @@ |
|||
/* |
|||
* 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 JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace OpenIddict.Infrastructure { |
|||
/// <summary>
|
|||
/// Exposes the common services used by OpenIddict.
|
|||
/// </summary>
|
|||
public class OpenIddictServices<TApplication, TAuthorization, TScope, TToken> |
|||
where TApplication : class where TAuthorization : class |
|||
where TScope : class where TToken : class { |
|||
public OpenIddictServices([NotNull] IServiceProvider services) { |
|||
Services = services; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="OpenIddictApplicationManager{TApplication}"/>.
|
|||
/// </summary>
|
|||
public virtual OpenIddictApplicationManager<TApplication> Applications => |
|||
Services.GetRequiredService<OpenIddictApplicationManager<TApplication>>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets the optional <see cref="HttpContext"/>.
|
|||
/// </summary>
|
|||
public virtual HttpContext Context => Services.GetService<IHttpContextAccessor>()?.HttpContext; |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="ILogger"/>.
|
|||
/// </summary>
|
|||
public virtual ILogger Logger => |
|||
Services.GetRequiredService<ILogger<OpenIddictProvider<TApplication, TAuthorization, TScope, TToken>>>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="OpenIddictOptions"/>.
|
|||
/// </summary>
|
|||
public virtual OpenIddictOptions Options => Services.GetRequiredService<IOptions<OpenIddictOptions>>().Value; |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="IServiceProvider"/> used to resolve services.
|
|||
/// </summary>
|
|||
public virtual IServiceProvider Services { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="OpenIddictTokenManager{TToken}"/>.
|
|||
/// </summary>
|
|||
public virtual OpenIddictTokenManager<TToken> Tokens => Services.GetRequiredService<OpenIddictTokenManager<TToken>>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
/* |
|||
* 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 JetBrains.Annotations; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using OpenIddict.Models; |
|||
|
|||
namespace OpenIddict.EntityFramework { |
|||
/// <summary>
|
|||
/// Represents a model customizer able to register the entity sets
|
|||
/// required by the OpenIddict stack in an Entity Framework context.
|
|||
/// </summary>
|
|||
public class OpenIddictCustomizer<TApplication, TAuthorization, TScope, TToken, TKey> : ModelCustomizer |
|||
where TApplication : OpenIddictApplication<TKey, TToken> |
|||
where TAuthorization : OpenIddictAuthorization<TKey, TToken> |
|||
where TScope : OpenIddictScope<TKey> |
|||
where TToken : OpenIddictToken<TKey> |
|||
where TKey : IEquatable<TKey> { |
|||
public override void Customize([NotNull] ModelBuilder builder, [NotNull] DbContext context) { |
|||
if (builder == null) { |
|||
throw new ArgumentNullException(nameof(builder)); |
|||
} |
|||
|
|||
if (context == null) { |
|||
throw new ArgumentNullException(nameof(context)); |
|||
} |
|||
|
|||
// Register the OpenIddict entity sets.
|
|||
builder.UseOpenIddict<TApplication, TAuthorization, TScope, TToken, TKey>(); |
|||
|
|||
base.Customize(builder, context); |
|||
} |
|||
} |
|||
} |
|||
@ -1,199 +0,0 @@ |
|||
/* |
|||
* 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 Microsoft.AspNetCore.Identity.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
|
|||
namespace OpenIddict { |
|||
/// <summary>
|
|||
/// Represents an OpenIddict-powered Entity Framework context.
|
|||
/// </summary>
|
|||
public class OpenIddictDbContext : OpenIddictDbContext<IdentityUser> { |
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context without configuring the Entity Framework options.
|
|||
/// </summary>
|
|||
protected OpenIddictDbContext() { } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context.
|
|||
/// </summary>
|
|||
/// <param name="options">The options used to configure the Entity Framework context.</param>
|
|||
public OpenIddictDbContext(DbContextOptions options) : base(options) { } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Represents an OpenIddict-powered Entity Framework context.
|
|||
/// </summary>
|
|||
/// <typeparam name="TUser">The type of the User entity.</typeparam>
|
|||
public class OpenIddictDbContext<TUser> : OpenIddictDbContext<TUser, IdentityRole, OpenIddictApplication, |
|||
OpenIddictAuthorization, |
|||
OpenIddictScope, |
|||
OpenIddictToken, string> |
|||
where TUser : IdentityUser { |
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context without configuring the Entity Framework options.
|
|||
/// </summary>
|
|||
protected OpenIddictDbContext() { } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context.
|
|||
/// </summary>
|
|||
/// <param name="options">The options used to configure the Entity Framework context.</param>
|
|||
public OpenIddictDbContext(DbContextOptions options) : base(options) { } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Represents an OpenIddict-powered Entity Framework context.
|
|||
/// </summary>
|
|||
/// <typeparam name="TUser">The type of the User entity.</typeparam>
|
|||
/// <typeparam name="TRole">The type of the Role entity.</typeparam>
|
|||
public class OpenIddictDbContext<TUser, TRole> : OpenIddictDbContext<TUser, TRole, OpenIddictApplication, |
|||
OpenIddictAuthorization, |
|||
OpenIddictScope, |
|||
OpenIddictToken, string> |
|||
where TUser : IdentityUser |
|||
where TRole : IdentityRole { |
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context without configuring the Entity Framework options.
|
|||
/// </summary>
|
|||
protected OpenIddictDbContext() { } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context.
|
|||
/// </summary>
|
|||
/// <param name="options">The options used to configure the Entity Framework context.</param>
|
|||
public OpenIddictDbContext(DbContextOptions options) : base(options) { } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Represents an OpenIddict-powered Entity Framework context.
|
|||
/// </summary>
|
|||
/// <typeparam name="TUser">The type of the User entity.</typeparam>
|
|||
/// <typeparam name="TRole">The type of the Role entity.</typeparam>
|
|||
/// <typeparam name="TKey">The type of the primary key used by the Identity/OpenIddict entities.</typeparam>
|
|||
public class OpenIddictDbContext<TUser, TRole, TKey> : OpenIddictDbContext<TUser, TRole, OpenIddictApplication<TKey>, |
|||
OpenIddictAuthorization<TKey>, |
|||
OpenIddictScope<TKey>, |
|||
OpenIddictToken<TKey>, TKey> |
|||
where TUser : IdentityUser<TKey> |
|||
where TRole : IdentityRole<TKey> |
|||
where TKey : IEquatable<TKey> { |
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context without configuring the Entity Framework options.
|
|||
/// </summary>
|
|||
protected OpenIddictDbContext() { } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context.
|
|||
/// </summary>
|
|||
/// <param name="options">The options used to configure the Entity Framework context.</param>
|
|||
public OpenIddictDbContext(DbContextOptions options) : base(options) { } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Represents an OpenIddict-powered Entity Framework context.
|
|||
/// </summary>
|
|||
/// <typeparam name="TUser">The type of the User entity.</typeparam>
|
|||
/// <typeparam name="TRole">The type of the Role entity.</typeparam>
|
|||
/// <typeparam name="TApplication">The type of the Application entity.</typeparam>
|
|||
/// <typeparam name="TAuthorization">The type of the Authorization entity.</typeparam>
|
|||
/// <typeparam name="TScope">The type of the Scope entity.</typeparam>
|
|||
/// <typeparam name="TToken">The type of the Token entity.</typeparam>
|
|||
/// <typeparam name="TKey">The type of the primary key used by the Identity/OpenIddict entities.</typeparam>
|
|||
public class OpenIddictDbContext<TUser, TRole, TApplication, TAuthorization, TScope, TToken, TKey> : IdentityDbContext<TUser, TRole, TKey> |
|||
where TUser : IdentityUser<TKey> |
|||
where TRole : IdentityRole<TKey> |
|||
where TApplication : OpenIddictApplication<TKey, TToken> |
|||
where TAuthorization : OpenIddictAuthorization<TKey, TToken> |
|||
where TScope : OpenIddictScope<TKey> |
|||
where TToken : OpenIddictToken<TKey> |
|||
where TKey : IEquatable<TKey> { |
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context without configuring the Entity Framework options.
|
|||
/// </summary>
|
|||
protected OpenIddictDbContext() { } |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new OpenIddict context.
|
|||
/// </summary>
|
|||
/// <param name="options">The options used to configure the Entity Framework context.</param>
|
|||
public OpenIddictDbContext(DbContextOptions options) : base(options) { } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the database set containing the applications.
|
|||
/// </summary>
|
|||
public DbSet<TApplication> Applications { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the database set containing the authorizations.
|
|||
/// </summary>
|
|||
public DbSet<TAuthorization> Authorizations { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the database set containing the scopes.
|
|||
/// </summary>
|
|||
public DbSet<TScope> Scopes { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the database set containing the tokens.
|
|||
/// </summary>
|
|||
public DbSet<TToken> Tokens { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Registers the OpenIddict entities in the Entity Framework context.
|
|||
/// </summary>
|
|||
/// <param name="builder">The model builder used by Entity Framework.</param>
|
|||
protected override void OnModelCreating(ModelBuilder builder) { |
|||
base.OnModelCreating(builder); |
|||
|
|||
// Warning: optional foreign keys MUST NOT be added as CLR properties because
|
|||
// Entity Framework would throw an exception due to the TKey generic parameter
|
|||
// being non-nullable when using value types like short, int, long or Guid.
|
|||
|
|||
// Configure the TApplication entity.
|
|||
builder.Entity<TApplication>(entity => { |
|||
entity.HasKey(application => application.Id); |
|||
|
|||
entity.HasIndex(application => application.ClientId) |
|||
.IsUnique(unique: true); |
|||
|
|||
entity.HasMany(application => application.Tokens) |
|||
.WithOne() |
|||
.HasForeignKey("ApplicationId") |
|||
.IsRequired(required: false); |
|||
|
|||
entity.ToTable("OpenIddictApplications"); |
|||
}); |
|||
|
|||
// Configure the TAuthorization entity.
|
|||
builder.Entity<TAuthorization>(entity => { |
|||
entity.HasKey(authorization => authorization.Id); |
|||
|
|||
entity.HasMany(authorization => authorization.Tokens) |
|||
.WithOne() |
|||
.HasForeignKey("AuthorizationId") |
|||
.IsRequired(required: false); |
|||
|
|||
entity.ToTable("OpenIddictAuthorizations"); |
|||
}); |
|||
|
|||
// Configure the TScope entity.
|
|||
builder.Entity<TScope>(entity => { |
|||
entity.HasKey(scope => scope.Id); |
|||
|
|||
entity.ToTable("OpenIddictScopes"); |
|||
}); |
|||
|
|||
// Configure the TToken entity.
|
|||
builder.Entity<TToken>(entity => { |
|||
entity.HasKey(token => token.Id); |
|||
|
|||
entity.ToTable("OpenIddictTokens"); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
/* |
|||
* 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 Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using OpenIddict.Models; |
|||
|
|||
namespace OpenIddict.EntityFramework { |
|||
public class OpenIddictExtension<TApplication, TAuthorization, TScope, TToken, TKey> : IDbContextOptionsExtension |
|||
where TApplication : OpenIddictApplication<TKey, TToken> |
|||
where TAuthorization : OpenIddictAuthorization<TKey, TToken> |
|||
where TScope : OpenIddictScope<TKey> |
|||
where TToken : OpenIddictToken<TKey> |
|||
where TKey : IEquatable<TKey> { |
|||
public void ApplyServices(IServiceCollection services) { |
|||
if (services == null) { |
|||
throw new ArgumentNullException(nameof(services)); |
|||
} |
|||
|
|||
services.AddSingleton<IModelCustomizer, OpenIddictCustomizer<TApplication, TAuthorization, TScope, TToken, TKey>>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
|
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
|||
<PropertyGroup Label="Globals"> |
|||
<ProjectGuid>0102a6cc-41a6-4b34-b49e-65afe95882bb</ProjectGuid> |
|||
<RootNamespace>OpenIddict.Models</RootNamespace> |
|||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
|||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
|||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
</PropertyGroup> |
|||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
</Project> |
|||
@ -0,0 +1,43 @@ |
|||
{ |
|||
"version": "1.0.0-beta2-*", |
|||
|
|||
"description": "Provides default entities for OpenIddict, that can be used by the EntityFramework stores.", |
|||
"authors": [ "Kévin Chalet" ], |
|||
|
|||
"packOptions": { |
|||
"owners": [ "Kévin Chalet" ], |
|||
|
|||
"projectUrl": "https://github.com/openiddict/openiddict-core", |
|||
"iconUrl": "https://avatars3.githubusercontent.com/u/13908567?s=64", |
|||
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html", |
|||
|
|||
"repository": { |
|||
"type": "git", |
|||
"url": "git://github.com/openiddict/openiddict-core" |
|||
}, |
|||
|
|||
"tags": [ |
|||
"aspnetcore", |
|||
"authentication", |
|||
"jwt", |
|||
"openidconnect", |
|||
"openiddict", |
|||
"security" |
|||
] |
|||
}, |
|||
|
|||
"buildOptions": { |
|||
"warningsAsErrors": true, |
|||
"nowarn": [ "CS1591" ], |
|||
"xmlDoc": true |
|||
}, |
|||
|
|||
"dependencies": { |
|||
"System.Collections": "4.0.11", |
|||
"System.Runtime": "4.1.0" |
|||
}, |
|||
|
|||
"frameworks": { |
|||
"netstandard1.0": { } |
|||
} |
|||
} |
|||
@ -1,238 +1,56 @@ |
|||
using System; |
|||
using AspNet.Security.OpenIdConnect.Primitives; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Builder.Internal; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Moq; |
|||
using OpenIddict.Infrastructure; |
|||
using OpenIddict.Models; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Core.Tests { |
|||
public class OpenIddictExtensionsTests { |
|||
[Fact] |
|||
public void AddOpenIddict_RegistersProvider() { |
|||
[Theory] |
|||
[InlineData(typeof(OpenIddictApplicationManager<OpenIddictApplication>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<OpenIddictAuthorization>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<OpenIddictScope>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<OpenIddictToken>))] |
|||
public void AddOpenIddict_KeyTypeDefaultsToString(Type type) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
// Act
|
|||
services.AddOpenIddict<object, object, object, object>(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
services.AddOpenIddict(); |
|||
|
|||
// Assert
|
|||
Assert.IsType(typeof(OpenIddictProvider<object, object, object, object>), options.Value.Provider); |
|||
Assert.Contains(services, service => service.ImplementationType == type); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(typeof(IDataProtectionProvider))] |
|||
[InlineData(typeof(OpenIddictApplicationManager<object>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<object>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<object>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<object>))] |
|||
[InlineData(typeof(OpenIddictServices<object, object, object, object>))] |
|||
public void AddOpenIddict_RegistersCoreServices(Type type) { |
|||
[InlineData(typeof(OpenIddictApplicationManager<OpenIddictApplication<Guid, OpenIddictToken<Guid>>>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<OpenIddictAuthorization<Guid, OpenIddictToken<Guid>>>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<OpenIddictScope<Guid>>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<OpenIddictToken<Guid>>))] |
|||
public void AddOpenIddict_KeyTypeCanBeOverriden(Type type) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
// Act
|
|||
services.AddOpenIddict<object, object, object, object>(); |
|||
services.AddOpenIddict<Guid>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(services, service => service.ServiceType == type); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenNoDistributedCacheIsRegisteredIfRequestCachingIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict<object, object, object, object>() |
|||
.EnableRequestCaching(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("A distributed cache implementation must be registered in the OpenIddict options " + |
|||
"or in the dependency injection container when enabling request caching support.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenNoSigningCredentialsIsRegistered() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOpenIddict<object, object, object, object>(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("At least one signing key must be registered. 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 UseOpenIddict_AnExceptionIsThrownWhenNoFlowIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict<object, object, object, object>() |
|||
.AddEphemeralSigningKey(); |
|||
|
|||
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); |
|||
Assert.Contains(services, service => service.ImplementationType == type); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.Implicit)] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenAuthorizationEndpointIsDisabled(string flow) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict<object, object, object, object>() |
|||
.AddEphemeralSigningKey() |
|||
.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_AnExceptionIsThrownWhenTokenEndpointIsDisabled(string flow) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict<object, object, object, object>() |
|||
.AddEphemeralSigningKey() |
|||
.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_OpenIdConnectServerMiddlewareIsRegistered() { |
|||
[InlineData(typeof(OpenIddictApplicationManager<object>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<object>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<object>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<object>))] |
|||
public void AddOpenIddict_DefaultEntitiesCanBeReplaced(Type type) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict<object, object, object, object>() |
|||
.AddEphemeralSigningKey() |
|||
.AllowImplicitFlow() |
|||
.EnableAuthorizationEndpoint("/connect/authorize"); |
|||
|
|||
var builder = new Mock<IApplicationBuilder>(); |
|||
builder.SetupGet(mock => mock.ApplicationServices) |
|||
.Returns(services.BuildServiceProvider()); |
|||
|
|||
// Act
|
|||
builder.Object.UseOpenIddict(); |
|||
services.AddOpenIddict<object, object, object, object>(); |
|||
|
|||
// Assert
|
|||
builder.Verify(mock => mock.Use(It.IsAny<Func<RequestDelegate, RequestDelegate>>()), Times.Once()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsAuthorizationCodeFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.AuthorizationCode); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsAuthorizationCodeFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsClientCredentialsFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.ClientCredentials); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsClientCredentialsFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsImplicitFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Implicit); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsImplicitFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsPasswordFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Password); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsPasswordFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsRefreshTokenFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.RefreshToken); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsRefreshTokenFlowEnabled()); |
|||
Assert.Contains(services, service => service.ServiceType == type); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,526 @@ |
|||
using System; |
|||
using System.IdentityModel.Tokens.Jwt; |
|||
using System.Reflection; |
|||
using AspNet.Security.OpenIdConnect.Primitives; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Tests { |
|||
public class OpenIddictBuilderTests { |
|||
[Fact] |
|||
public void Configure_OptionsAreCorrectlyAmended() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 AddEphemeralSigningKey_SigningKeyIsCorrectlyAdded() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AddSigningCertificate( |
|||
assembly: typeof(OpenIddictBuilderTests).GetTypeInfo().Assembly, |
|||
resource: "OpenIddict.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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 EnableAuthorizationEndpoint_AuthorizationEndpointIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 EnableTokenEndpoint_TokenEndpointIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 UseDataProtectionProvider_DefaultProviderIsReplaced() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
builder.UseJsonWebTokens(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.IsType(typeof(JwtSecurityTokenHandler), options.Value.AccessTokenHandler); |
|||
} |
|||
} |
|||
} |
|||
@ -1,60 +1,731 @@ |
|||
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.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace OpenIddict.Tests { |
|||
public class OpenIddictExtensionsTests { |
|||
[Fact] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenServicesAreNotRegistered() { |
|||
// 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_AnExceptionIsThrownWhenNoDistributedCacheIsRegisteredIfRequestCachingIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.EnableRequestCaching(); |
|||
|
|||
var builder = new ApplicationBuilder(services.BuildServiceProvider()); |
|||
|
|||
// Act and assert
|
|||
var exception = Assert.Throws<InvalidOperationException>(() => builder.UseOpenIddict()); |
|||
|
|||
Assert.Equal("A distributed cache implementation must be registered in the OpenIddict options " + |
|||
"or in the dependency injection container when enabling request caching support.", exception.Message); |
|||
} |
|||
|
|||
[Fact] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenNoSigningCredentialsIsRegistered() { |
|||
// 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 signing key must be registered. 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 UseOpenIddict_AnExceptionIsThrownWhenNoFlowIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.AddEphemeralSigningKey(); |
|||
|
|||
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(typeof(OpenIddictApplicationManager<OpenIddictApplication<Guid>>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<OpenIddictAuthorization<Guid>>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<OpenIddictScope<Guid>>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<OpenIddictToken<Guid>>))] |
|||
public void AddOpenIddict_RegistersCoreManagers(Type type) { |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] |
|||
[InlineData(OpenIdConnectConstants.GrantTypes.Implicit)] |
|||
public void UseOpenIddict_AnExceptionIsThrownWhenAuthorizationEndpointIsDisabled(string flow) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.AddEphemeralSigningKey() |
|||
.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_AnExceptionIsThrownWhenTokenEndpointIsDisabled(string flow) { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
|
|||
services.AddOpenIddict() |
|||
.AddEphemeralSigningKey() |
|||
.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 Configure_OptionsAreCorrectlyAmended() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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() |
|||
.AddEphemeralSigningKey() |
|||
.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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
services.AddOpenIddict<OpenIddictDbContext, Guid>(); |
|||
builder.AddEphemeralSigningKey(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(services, service => service.ImplementationType == type); |
|||
Assert.Equal(1, options.Value.SigningCredentials.Count); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(typeof(OpenIddictApplicationStore<OpenIddictApplication<Guid>, OpenIddictToken<Guid>, OpenIddictDbContext, Guid>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationStore<OpenIddictAuthorization<Guid>, OpenIddictToken<Guid>, OpenIddictDbContext, Guid>))] |
|||
[InlineData(typeof(OpenIddictScopeStore<OpenIddictScope<Guid>, OpenIddictDbContext, Guid>))] |
|||
[InlineData(typeof(OpenIddictTokenStore<OpenIddictToken<Guid>, OpenIddictAuthorization<Guid>, OpenIddictDbContext, Guid>))] |
|||
public void AddOpenIddict_RegistersEntityFrameworkStores(Type type) { |
|||
[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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
services.AddOpenIddict<OpenIddictDbContext, Guid>(); |
|||
builder.AddEphemeralSigningKey(algorithm); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
var credentials = options.Value.SigningCredentials[0]; |
|||
|
|||
// Assert
|
|||
Assert.Contains(services, service => service.ImplementationType == type); |
|||
Assert.Equal(algorithm, credentials.Algorithm); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(typeof(OpenIddictApplicationManager<OpenIddictApplication>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationManager<OpenIddictAuthorization>))] |
|||
[InlineData(typeof(OpenIddictScopeManager<OpenIddictScope>))] |
|||
[InlineData(typeof(OpenIddictTokenManager<OpenIddictToken>))] |
|||
[InlineData(typeof(OpenIddictApplicationStore<OpenIddictApplication, OpenIddictToken, OpenIddictDbContext, string>))] |
|||
[InlineData(typeof(OpenIddictAuthorizationStore<OpenIddictAuthorization, OpenIddictToken, OpenIddictDbContext, string>))] |
|||
[InlineData(typeof(OpenIddictScopeStore<OpenIddictScope, OpenIddictDbContext, string>))] |
|||
[InlineData(typeof(OpenIddictTokenStore<OpenIddictToken, OpenIddictAuthorization, OpenIddictDbContext, string>))] |
|||
public void AddOpenIddict_KeyTypeDefaultsToString(Type type) { |
|||
[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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
builder.AddSigningCertificate( |
|||
assembly: typeof(OpenIddictBuilderTests).GetTypeInfo().Assembly, |
|||
resource: "OpenIddict.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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
services.AddOpenIddict<OpenIddictDbContext>(); |
|||
builder.DisableConfigurationEndpoint(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.Contains(services, service => service.ImplementationType == type); |
|||
Assert.Equal(PathString.Empty, options.Value.ConfigurationEndpointPath); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DisableCryptographyEndpoint_CryptographyEndpointIsDisabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 EnableAuthorizationEndpoint_AuthorizationEndpointIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 EnableTokenEndpoint_TokenEndpointIsEnabled() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 = new OpenIddictBuilder(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 UseDataProtectionProvider_DefaultProviderIsReplaced() { |
|||
// Arrange
|
|||
var services = new ServiceCollection(); |
|||
services.AddOptions(); |
|||
|
|||
var builder = new OpenIddictBuilder(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 = new OpenIddictBuilder(services); |
|||
|
|||
// Act
|
|||
builder.UseJsonWebTokens(); |
|||
|
|||
var provider = services.BuildServiceProvider(); |
|||
var options = provider.GetRequiredService<IOptions<OpenIddictOptions>>(); |
|||
|
|||
// Assert
|
|||
Assert.IsType(typeof(JwtSecurityTokenHandler), options.Value.AccessTokenHandler); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsAuthorizationCodeFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.AuthorizationCode); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsAuthorizationCodeFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsClientCredentialsFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.ClientCredentials); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsClientCredentialsFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsImplicitFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Implicit); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsImplicitFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsPasswordFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.Password); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsPasswordFlowEnabled()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(true)] |
|||
[InlineData(false)] |
|||
public void IsRefreshTokenFlowEnabled_ReturnsAppropriateResult(bool enabled) { |
|||
// Arrange
|
|||
var options = new OpenIddictOptions(); |
|||
|
|||
if (enabled) { |
|||
options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.RefreshToken); |
|||
} |
|||
|
|||
// Act and assert
|
|||
Assert.Equal(enabled, options.IsRefreshTokenFlowEnabled()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue