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

时间:2014-10-22 13:09:18

标签: c# entity-framework validation iidentity

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

我们正在使用Identity Framework,我最初的意图是像这样扩展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只能将一个字符串作为参数。有没有办法在这里输入用户名/自定义对象,或者在保存信息之前将密码字符串与用户名进行比较?

修改

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

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

2 个答案:

答案 0 :(得分:1)

而不是使用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>(...);
}

答案 1 :(得分: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);