我正在进行自定义密码验证,它会进行一系列额外检查,理想情况下包括用户尝试创建的密码不包含其用户名的任何排列。
我们正在使用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);
答案 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);