ASP.net Core 2.0的密码历史记录

4
我的要求之一是检查过去一年的最近5个密码历史记录,以确保客户没有重复使用密码。
我已经在用户实体上创建了密码实体和密码集合。
我需要创建一个自定义用户管理器,继承自 "UserManager" 并覆盖添加/更新密码以填充历史记录的方法。我还必须创建一个自定义密码验证器,它从 "PasswordValidator" 继承并重写 "ValidateAsync" 方法。
如何在 .Net Core 2.0 中注册这些自定义实现呢?您是否需要用所有单独的依赖项注入调用替换 "services.AddIdentity" 帮助程序?或者有没有一种方法只覆盖 "UserManager" 和 "PasswordValidator" 部分?
2个回答

3
您可以通过简单地使用AddIdentity()调用注册您的服务来替换默认注册的服务。依赖注入容器会保留所有的注册信息,但是当服务请求一个实例时,它将仅使用该类型的最新注册信息。所以您只需要确保您以完全相同的方式注册您的服务,原始服务也是这样注册的。如果不确定,请参考实现以查看哪些服务被注册了。在您的情况下,您可能想要做以下操作:
services.AddIdentity<MyUser, MyRole>();
services.AddScoped<UserManager<MyUser>, CustomUserManager>();
services.AddScoped<IPasswordValidator<MyUser>, CustomPasswordValidator>();

4
有趣的是...在查看实现时,我注意到他们使用了services.TryAddTransient。根据Intellisense,如果服务类型已经被注册,这只会注册服务类型一次。现在我想知道是在调用AddIdentity()之前还是之后进行注册最好。我将尝试两种方法并发布结果。谢谢! - Sam
1
确实,由于使用了TryAddScopedTryAddTransient,我能够在调用AddIdentity之前添加自定义实现。 - Sam
太好了,知道这个消息真是太好了!感谢您的反馈 :) - poke

1
另一个适用于您的情况并可适用于多种其他情况的想法是寻找一种方法,使您可以添加不同的功能和身份验证。

例如:

  services.AddIdentity<User, IdentityRole>()
                .AddUserManager<UserManager>()
                .AddDefaultTokenProviders();

用于指定不同的 UserManager 实现。

在您的情况下,您可以使用 AddPasswordValidator 方法:

services.AddIdentity<User, IdentityRole>(options =>
{
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonLetterOrDigit = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
})
.AddDefaultTokenProviders()
.AddPasswordValidator<SameCharacterPasswordValidator<User>>();

Identity框架将为您完成所有的DI工作:

 public virtual IdentityBuilder AddPasswordValidator<TUser>() where TUser : class
 {
    return this.AddScoped(typeof (IPasswordValidator<>).MakeGenericType(this.UserType), typeof (TUser));
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接