Reputation: 952
Can I update my application validation rules after startup?
I tried something like this, but I got stuck in how I'll persist that Information.
public void UpdatePasswordValidation(SystemConfig config)
{
var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
manager.PasswordValidator = new CustomPasswordValidator
{
DigitLength = config.PswNumber ?? 0,
EspecialCharLength = config.PswEspecialChar ?? 0,
LowercaseLength = config.PswLower ?? 0,
RequiredLength = config.PswMinLength ?? 0,
UppercaseLength = config.PswUpper ?? 0,
};
//How do I persist these rules in owin context?
}
Thanks in advance. Sorry for my poor english :(.
Upvotes: 0
Views: 872
Reputation: 1535
If I understand what you are trying to do, you are attempting to:
then you can achieve this by utilizing both a custom password validator and with your web.config to store the values. The only issue I see with web.config is I think that upon changes it will restart your MVC site. If this was an issue, you could create an admin page which allowed the user to modify these values and then save the values to a db.
To create a custom validator you could impliment the IIdentityValidator interface and then inside of your UserManager class inside the constructor swap out the default PasswordValidator for your custom one. Like so:
public class CustomPasswordValidator : IIdentityValidator<string>
{
public int RequiredLength { get; set; }
public CustomPasswordValidator(int? length)
{
int webConfigMinimumPasswordLength;
if (int.TryParse(WebConfigurationManager.AppSettings["MinimumPasswordLength"],
out webConfigMinimumPasswordLength))
{
Console.WriteLine("Parsing config failed");
webConfigMinimumPasswordLength = 6; // just go back to default
}
RequiredLength = length ?? webConfigMinimumPasswordLength;
}
public Task<IdentityResult> ValidateAsync(string item)
{
if (String.IsNullOrEmpty(item) || item.Length < RequiredLength)
{
return Task.FromResult(IdentityResult.Failed(String.Format("Password should be of length {0}",RequiredLength)));
}
string pattern = @"^(?=.*[0-9])(?=.*[!@#$%^&*])[0-9a-zA-Z!@#$%^&*0-9]{10,}$";
if (!Regex.IsMatch(item, pattern))
{
return Task.FromResult(IdentityResult.Failed("Password should have one numeral and one special character"));
}
return Task.FromResult(IdentityResult.Success);
}
}
then go into your UserManager deceleration (usually inside IdentityConfig.cs)
public class ApplicationUserManager : UserManager<ApplicationUser[PR6] >
{
public ApplicationUserManager() : base(new UserStore<ApplicationUser(new ApplicationDbContext()))
{
// add the line below to your UserManager
PasswordValidator = new CustomPasswordValidator();
}
}
Hope this helps, if there are any more issues feel free to comment, I was unable to get this into an actual MVC project and ensure what I slapped together actually worked!
For more reading on Custom Password Validators, have a look at: http://blogs.msdn.com/b/webdev/archive/2014/01/06/implementing-custom-password-policy-using-asp-net-identity.aspx
Upvotes: 2