0

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

我们正在使用身份框架,我的初衷是像这样扩展 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);
    }
}

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

编辑

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

用户管理器:

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);
4

2 回答 2

1

而不是使用PasswordValidatoruse the UserValidatorwhich 将允许您使用您的用户对象作为参数。for 的类型ValidateAsync来自泛型参数。

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

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

public ApplicationUserManager(IUserStore<User> store)
        : base(store)
{
    UserValidator = new MyUserValidator<User>(...);
}
于 2014-10-22T13:19:57.020 回答
0

只需添加一个/多个您希望的类型的字段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);
于 2014-10-22T13:27:52.923 回答