有没有办法将用户信息传递给IIdentityValidator



我正在研究一个自定义密码验证,它将进行一系列额外的检查,理想情况下包括用户尝试创建的密码不包含其用户名的任何排列。

我们正在使用身份框架,我的初衷是像这样扩展IIdentityValidator:

public class StrongPasswordValidator : IIdentityValidator<string>
{
    public int MinimumLength { get; set; }
    public int MaximumLength { get; set; }
    public void CustomPasswordValidator(int minimumLength, int maximumLength)
    {
        this.MinimumLength = minimumLength;
        this.MaximumLength = maximumLength;
    }
    public Task<IdentityResult> ValidateAsync(string item)
    {
        if (item.Length < MinimumLength)
        {
            return Task.FromResult(IdentityResult.Failed("Password must be a minimum of " + MinimumLength + " characters."));
        }
        if (item.Length > MaximumLength)
        {
            return Task.FromResult(IdentityResult.Failed("Password must be a maximum of " + MaximumLength + " characters."));
        }
        return Task.FromResult(IdentityResult.Success);
    }
}

但这只能将字符串作为每个用户管理器的参数。有没有办法在这里也拉入用户名/自定义对象,或者在保留信息之前将密码字符串与用户名进行比较?

编辑

对于上下文,这是密码验证器的设置和使用方式。

用户管理员:

public CustomUserManager(IUserStore<User> store,
        IPasswordHasher passwordHasher,
        IIdentityMessageService emailService)
        : base(store)
    {
        //Other validators
        PasswordValidator = new StrongPasswordValidator
        {
            MinimumLength = 8,
            MaximumLength = 100
        };
        PasswordHasher = passwordHasher;
        EmailService = emailService;
    }

用户创建:

var userManager = new CustomUserManager(userStore,
                new BCryptHasher(), emailService.Object);    
userManager.CreateAsync(user, Password);

不要使用PasswordValidator而是使用 UserValidator,这将允许您使用用户对象作为参数。ValidateAsync的类型来自泛型参数。

public class MyUserValidator : IIdentityValidator<User>
{
    public Task<IdentityResult> ValidateAsync(User item)
    {
        ...
    }
}

在您的用户管理器中注册它...

public ApplicationUserManager(IUserStore<User> store)
        : base(store)
{
    UserValidator = new MyUserValidator<User>(...);
}

只需在 StrongPasswordValidator 中添加一个或多个您希望类型的字段,并在构造函数中注入值

public class StrongPasswordValidator : IIdentityValidator<string>
{
    public int MinimumLength { get; set; }
    public int MaximumLength { get; set; }
    private readonly MyCustomObjectType _myCustomObject;
    public void CustomPasswordValidator(int minimumLength, int maximumLength, 
                                        MyCustomObjectType myCustomObject)
    {
        // guard clause
        if(myCustomObject == null)
        {
           throw new ArgumentExpcetion("myCustomObject was not provided.");
        }
        _myCustomObject = myCustomObject;
        this.MinimumLength = minimumLength;
        this.MaximumLength = maximumLength;
    }
    public Task<IdentityResult> ValidateAsync(string item)
    {
        // use _myCustomObject here
        if (item.Length < MinimumLength)
        {
            return Task.FromResult(IdentityResult.Failed("Password must be a minimum of " + MinimumLength + " characters."));
        }
        if (item.Length > MaximumLength)
        {
            return Task.FromResult(IdentityResult.Failed("Password must be a maximum of " + MaximumLength + " characters."));
        }
        return Task.FromResult(IdentityResult.Success);
    }
}

现在,当您创建 StrongPasswordValidator 的实例时,您可以注入自定义对象。

MyCustomObjectType myCustomObject = new MyCustomObjectType();
UserManager.PasswordValidator = new StrongPasswordValidator(6, 10, myCustomObject);

编辑

根据更新的帖子,是什么阻止您通过将所需的对象传递给其构造函数来更新StrongPasswordValidator

public CustomUserManager(IUserStore<User> store,
        IPasswordHasher passwordHasher,
        IIdentityMessageService emailService)
        : base(store)
    {
        //Other validators
        MyCustomObjectType myCustomObject = new MyCustomObjectType();
        PasswordValidator = new StrongPasswordValidator(8, 100, myCustomObject);
        PasswordHasher = passwordHasher;
        EmailService = emailService;
    }

然后创建一个用户。

var userManager = new CustomUserManager(userStore,
                new BCryptHasher(), emailService.Object);    
userManager.CreateAsync(user, Password);

相关内容

  • 没有找到相关文章

最新更新