Есть ли способ передать пользовательскую информацию в IIdentityValidator?
Я работаю над пользовательской проверкой пароля, которая выполнит кучу дополнительных проверок, в том числе и то, что пароль, который пытается создать пользователь, не содержит изменений имени пользователя.
Мы используем 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 ответа
Вместо использования PasswordValidator
использовать UserValidator
что позволит вам использовать ваш пользовательский объект в качестве аргумента. Тип для ValidateAsync
исходит из общего параметра.
public class MyUserValidator : IIdentityValidator<User>
{
public Task<IdentityResult> ValidateAsync(User item)
{
...
}
}
В вашем usermanager зарегистрируйте его...
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);