diff --git a/src/Microsoft.AspNetCore.Identity/IdentityBuilder.cs b/src/Microsoft.AspNetCore.Identity/IdentityBuilder.cs index 4896b6009b..74252d1156 100644 --- a/src/Microsoft.AspNetCore.Identity/IdentityBuilder.cs +++ b/src/Microsoft.AspNetCore.Identity/IdentityBuilder.cs @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Identity /// /// Adds an for the . /// - /// The user type to validate. + /// The user validator type. /// The current instance. public virtual IdentityBuilder AddUserValidator() where T : class { @@ -70,13 +70,23 @@ namespace Microsoft.AspNetCore.Identity /// /// Adds an for the . /// - /// The role type to validate. + /// The role validator type. /// The current instance. public virtual IdentityBuilder AddRoleValidator() where T : class { return AddScoped(typeof(IRoleValidator<>).MakeGenericType(RoleType), typeof(T)); } + /// + /// Adds an for the . + /// + /// The type of the claims principal factory. + /// The current instance. + public virtual IdentityBuilder AddClaimsPrincipalFactory() where T : class + { + return AddScoped(typeof(IUserClaimsPrincipalFactory<>).MakeGenericType(UserType), typeof(T)); + } + /// /// Adds an . /// @@ -199,5 +209,23 @@ namespace Microsoft.AspNetCore.Identity Services.AddScoped(typeof(TRoleManager), services => services.GetRequiredService(managerType)); return AddScoped(managerType, typeof(TRoleManager)); } + + /// + /// Adds a for the . + /// + /// The type of the sign in manager to add. + /// The current instance. + public virtual IdentityBuilder AddSignInManager() where TSignInManager : class + { + var managerType = typeof(SignInManager<>).MakeGenericType(UserType); + var customType = typeof(TSignInManager); + if (managerType == customType || + !managerType.GetTypeInfo().IsAssignableFrom(customType.GetTypeInfo())) + { + throw new InvalidOperationException(Resources.FormatInvalidManagerType(customType.Name, "SignInManager", UserType.Name)); + } + Services.AddScoped(typeof(TSignInManager), services => services.GetRequiredService(managerType)); + return AddScoped(managerType, typeof(TSignInManager)); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Identity.Test/IdentityBuilderTest.cs b/test/Microsoft.AspNetCore.Identity.Test/IdentityBuilderTest.cs index 70144e1115..03acf210b3 100644 --- a/test/Microsoft.AspNetCore.Identity.Test/IdentityBuilderTest.cs +++ b/test/Microsoft.AspNetCore.Identity.Test/IdentityBuilderTest.cs @@ -4,10 +4,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Xunit; @@ -34,6 +37,19 @@ namespace Microsoft.AspNetCore.Identity.Test Assert.NotNull(thingy); } + [Fact] + public void CanOverridePrincipalFactory() + { + var services = new ServiceCollection().AddLogging(); + services.AddIdentity() + .AddClaimsPrincipalFactory() + .AddUserManager() + .AddUserStore() + .AddRoleStore(); + var thingy = services.BuildServiceProvider().GetRequiredService>() as MyClaimsPrincipalFactory; + Assert.NotNull(thingy); + } + [Fact] public void CanOverrideRoleValidator() { @@ -83,6 +99,22 @@ namespace Microsoft.AspNetCore.Identity.Test Assert.NotNull(myRoleManager); } + [Fact] + public void CanOverrideSignInManager() + { + var services = new ServiceCollection(); + services.AddSingleton() + .AddLogging() + .AddIdentity() + .AddUserStore() + .AddRoleStore() + .AddUserManager() + .AddClaimsPrincipalFactory() + .AddSignInManager(); + var myUserManager = services.BuildServiceProvider().GetRequiredService(typeof(SignInManager)) as MySignInManager; + Assert.NotNull(myUserManager); + } + [Fact] public void EnsureDefaultServices() { @@ -118,8 +150,10 @@ namespace Microsoft.AspNetCore.Identity.Test var builder = services.AddIdentity(); Assert.Throws(() => builder.AddUserManager>()); Assert.Throws(() => builder.AddRoleManager>()); + Assert.Throws(() => builder.AddSignInManager>()); Assert.Throws(() => builder.AddUserManager()); Assert.Throws(() => builder.AddRoleManager()); + Assert.Throws(() => builder.AddSignInManager()); } [Fact] @@ -254,11 +288,23 @@ namespace Microsoft.AspNetCore.Identity.Test } } + private class MySignInManager : SignInManager + { + public MySignInManager(UserManager manager, IHttpContextAccessor context, IUserClaimsPrincipalFactory claimsFactory) : base(manager, context, claimsFactory, null, null) { } + } + private class MyUserManager : UserManager { public MyUserManager(IUserStore store) : base(store, null, null, null, null, null, null, null, null) { } } + private class MyClaimsPrincipalFactory : UserClaimsPrincipalFactory + { + public MyClaimsPrincipalFactory(UserManager userManager, RoleManager roleManager, IOptions optionsAccessor) : base(userManager, roleManager, optionsAccessor) + { + } + } + private class MyRoleManager : RoleManager { public MyRoleManager(IRoleStore store,