Microsoft ASP.NET MVC comes with a built-in Authentication Template which you can use in your project. When you create a new ASP.NET MVC project in Visual Studio, you can click on Change Authentication button and select Individual User Accounts to include the default
Identity Template in your project,
When you open the project, you will notice the the following Authorization Template files have been added to your project,
Open IdentityConfig.cs file, which contains the default implementation of password validation rules,
- public class ApplicationUserManager : UserManager<ApplicationUser>
- {
-
-
- manager.PasswordValidator = new PasswordValidator
- {
- RequiredLength = 6,
- RequireNonLetterOrDigit = true,
- RequireDigit = true,
- RequireLowercase = true,
- RequireUppercase = true,
- };
-
-
- }
- }
Note: IdentityConfig.cs does not follow the most basic coding guideline, which is one class per file. I recommend moving the classes in this file to their respective files.
As you can see it is pretty straightforward to modify password strength rules, you can switch RequireDigit On/Off… you can change RequiredLength, etc.
But switching these rules wouldn’t produce a good password rule. Forcing users to include all
Uppercase, Lowercase, Digits and SpecialSymbols can be very frustrating for users who already have a secure password which satisfies some of the above rules, but not all. As an example,
Shopless uses the following password rule:
Password length should be a minimum of 8 characters and it should contain characters from at least 2 of the following groups: lower case, upper case, digits and special symbols.
In order to implement the above rule, we need to create our own CustomPasswordValidator.cs,
As you can see, it is pretty straightforward to modify password strength rules, you can set RequireDigit as True/False and change the min length, etc…
But switching these rules won’t produce a good password rule. Forcing users to include all Uppercase, Lowercase, Digits and SpecialSymbols can be very frustrating for users who already have a secure password which satisfies some of the above rules, but not all. A much better password rule would be:
- public class CustomPasswordValidator : IIdentityValidator<string>
- {
- public int MinLength { get; set; }
- public CustomPasswordValidator(int minLength)
- {
- MinLength = minLength;
- }
-
-
- public Task<IdentityResult> ValidateAsync(string password)
- {
- if (String.IsNullOrEmpty(password) || password.Length < MinLength) {
- return Task.FromResult(IdentityResult.Failed("Password too short"));
- }
-
- int counter = 0;
- List<string> patterns = new List<string>();
- patterns.Add(@"[a-z]");
- patterns.Add(@"[A-Z]");
- patterns.Add(@"[0-9]"); /
- patterns.Add(@"[!@#$%^&*\(\)_\+\-\={}<>,\.\|""'~`:;\\?\/\[\] ]"); // special symbols
-
-
- foreach (string p in patterns) {
- if (Regex.IsMatch(password, p)) {
- counter++;
- }
- }
-
- if (counter < 2) {
- return Task.FromResult(IdentityResult.Failed("Use characters from min 2 of these groups: lowercase, uppercase, digits, special symbols"));
- }
- return Task.FromResult(IdentityResult.Success);
- }
- }
Note
Don't forget to include white space in special symbols.
The above code is self explanatory, we are using regular expression to count the types of characters included in the password string. We fail the validation if password is too short or it does not contain at least 2 different character types.
And now we can use our own CustomPawwordValidator,
- public class ApplicationUserManager : UserManager<ApplicationUser>
- {
-
-
- manager.PasswordValidator = new CustomPasswordValidator(8 );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- }