Purpose
Many a time, entities want to implement a password policy and/or determine password strength for their security purposes.
The ASP .NET MVC Password Policy Validator allows the entity to set a password policy/determine password strength for users of their web systems.
Note. If your Zip extractor is unable to open the free download of the validator, use WinRar which can be freely downloaded from http://download.cnet.com/WinRAR-32-bit/3000-2250_4-10007677.html
Implementation Details
The Validator is built for ASP .NET MVC-based web systems.
It is an HTML Helper built using Extension Methods.
public static MvcHtmlString PasswordPolicyValidatorFor<TModel, TProperty>(
this HtmlHelper<TModel> Html,
System.Linq.Expressions.Expression<Func<TModel, TProperty>> Expression,
PasswordPolicy Policy,
string UserNameControlID,
PasswordStrength Strength,
string ScriptPath,
string ErrorMessage
)
{
}
The Policy and/or Strength requirements are set using objects of classes PasswordPolicy and PasswordStrength. These objects are parameters to the Helper. Null can be specified if any of them are not to be used.
The UserNameControlID is used to specify the ID of the user name textbox if validation has to be done to check that the user name is not part of the password.
The ScriptPath is used to specify the path to the PasswordPolicyValidator.js Javascript file.
The error message is used to specify the error to be shown when the password policy is not matched. This can be set from Resource files in the native languages of the culture too, in a multi-lingual setting.
Below are the PasswordPolicy and PasswordStrength classes which are used to set the requirements.
ThePasswordPolicy properties are
Property |
Explanation |
Accepted values |
UnicodeCharSetRanges |
Ranges of Unicode character sets. The validator defaults to English if the property is not specified. |
Comma-separated Upper/Uni case followed by Lower case (if applicable) of Unicode Character Set Ranges |
MinPasswordLength |
Minimum number of characters in password |
0 or greater |
MinNoOfUniCaseChars |
Minimum number of Unicase characters in the password. This property is to be used by Unicase languages. |
0 or greater |
MinNoOfLowerCaseChars |
Minimum number of lowercase characters in password |
0 or greater |
MinNoOfUpperCaseChars |
Minimum number of upper case characters in password |
0 or greater |
MinNoOfNumbers |
Minimum number of numbers in password |
0 or greater |
MinNoOfSymbols |
Minimum number of symbols in password |
0 or greater |
MaxNoOfAllowedRepetitions |
Max number of allowed repetitions of any character in the password |
0 or greater |
DisallowedChars |
Characters not allowed in password |
Empty or list of characters |
UserNameControlID |
Specified to confirm that the user name (case insensitive) is not part of the password |
The ID of the user name text box control |
The PasswordStrength properties are
Property |
Explanation |
Accepted values |
StrengthCategories |
The strength categories of the password. This property is mandatory for strength determination. |
Comma-separated list of strength categories |
StrengthColours |
The colors (supported in javascript) for the corresponding strength categories |
Comma-separated list of strength category colors |
UnicodeCharSetRanges |
Ranges of Unicode character sets. The validator defaults to English if the property is not specified. |
Comma-separated Upper/Uni case followed by Lower case (if applicable) of Unicode Character Set Ranges |
MinNoOfUniCaseCharsStrength |
List of no. of occurrences of Uni case characters to match for strength categories |
Empty or comma-separated list of positive integer values |
MinNoOfUpperCaseCharsStrength |
List of no. of occurrences of Upper Case characters to match for strength categories |
Empty or comma-separated list of positive integer values |
MinNoOfLowerCaseCharsStrength |
List of no. of occurrences of Lower Case characters to match for strength categories |
Empty or comma-separated list of positive integer values |
MinNoOfNumbersStrength |
List of no. of occurrences of Number characters to match for strength categories |
Empty or comma-separated list of positive integer values |
MinNoOfSymbolsStrength |
List of no. of occurrences of Symbols characters to match for strength categories |
Empty or comma-separated list of positive integer values |
MaxNoOfAllowedRepetitionsStrength |
List of allowed repetitions to match for strength categories |
Empty or comma-separated list of positive integer values |
MinPasswordLengthStrength |
List of password lengths to match strength categories |
Empty or comma-separated list of positive integer values |
Policy
Policy properties are those that the password MUST conform to.
Strength
Strength properties are used for determining the password strength.
StrengthCategories property is where the strength categories can be specified as below. This is mandatory for Strength determination.
StrengthCategories="weak, medium, strong"
Then, other relevant properties need to be specified for determining the strength. For eg.
MinNoOfLowerCaseCharsStrength="3,5,7"
means that 4 or fewer lowercase chars in the password are weak, 6 - 5 is medium and 7 or more is strong.
The Strength and Policy can be used independently of each other. Properties need not be specified if not required.
Note. It is good if the strength value of the lowest category is the same as the corresponding Min policy property if both Policy and Strength are being used.
Multi-lingual support
The validator supports the validation of passwords entered in languages supported in Unicode.
The property UnicodeCharSetRanges is used to specify the Unicode character set ranges of the desired language. If the language is case-sensitive then it is a comma-separated list of the upper-case character set range/s followed by the lower-case char set range/s. The Unicode ranges shown below will work for French, and German character sets.
UnicodeCharSetRanges = "A-Z\u00C0-\u00DE,a-z\u00DF-\u00F6\u00F8-\u00FF"
If the language is Uni-case then there is only one range. The Unicode range shown below is for the Japanese Hiragana range.
UnicodeCharSetRanges = "\u3040-\u309F"
More information on Unicode character set ranges can be found in the below Unicode Chart.
http://www.ssec.wisc.edu/%7Etomw/java/unicode.html
The properties MinNoOfLowerCaseChars and MinNoOfUpperCaseChars are only valid for case-sensitive languages while for Uni-case languages there is a property called MinNoOfUniCaseChars.
Using these properties, passwords in languages supported in Unicode can be validated. The Unicode ranges for different cultures can be stored in respective Resource files.
If the UnicodeCharSetRanges property is not specified, the validator defaults to English.
JQuery validation rule
The validation happens using a custom Rule for the JQuery validation plug-in as shown below. This rule calls a javascript function which does the validation. The rule is attached to the change/focus events of the password input textbox. It is also attached to the form submitted. You can change this function in the helper if you want the rule to be fired at different times.
Note. It is required to hook into the JQuery validation plug-in so that the error messages etc show up in the validation message elements.
function OnInit(PasswordControlID) {
$.ajaxSetup({ cache: false });
$(document).ready(function() {
jQuery.validator.addMethod("passwordPolicyValidate" + PasswordControlID + "", function(value, element) {
return PasswordPolicyValidatorValidate" + PasswordControlID + "();
}, '" + ErrorMessage + "');
});
$("#" + PasswordControlID + "").ready(function() {
$("#" + PasswordControlID + "").change(function() {
$('form').validate({
rules: {
" + PasswordControlID + ": { passwordPolicyValidate" + PasswordControlID + ": true }
}
});
});
$("#" + PasswordControlID + "").focus(function() {
$('form').validate({
rules: {
" + PasswordControlID + ": { passwordPolicyValidate" + PasswordControlID + ": true }
}
});
});
});
$(document).submit(function() {
$('form').validate({
rules: {
" + PasswordControlID + ": { passwordPolicyValidate" + PasswordControlID + ": true }
}
});
});
}
This validation plugin is included in the below
<script src="/Scripts/jquery.validate.js" type="text/javascript"></script>
script tag in the View page.
Code snippets
The PasswordPolicy property values are passed to a helper API GetExpression(). The GetExpression() API generates a Regular Expression based on the supplied properties.
public string GetExpression()
{
if (DisallowedChars.Length > 0)
{
DisallowedChars = DisallowedChars.Replace(@"\", @"\\");
}
string Unicase = String.IsNullOrEmpty(UnicodeCharSetRanges) ? "A-Z" : UnicodeCharSetRanges.Split(',')[0].Trim();
string Lowercase = String.IsNullOrEmpty(UnicodeCharSetRanges) ? "a-z" : (UnicodeCharSetRanges.Split(',').Length >= 2 ? UnicodeCharSetRanges.Split(',')[1] : "a-z");
return @"^"
+ (MaxNoOfAllowedRepetitions > -1 ? @"(?=^((.)(?!(.*?\2){" + (MaxNoOfAllowedRepetitions + 1).ToString() + @",}))+$)" : "")
+ (MinPasswordLength > -1 ? "(?=.{" + MinPasswordLength.ToString() + @",})" : "")
+ (MinNoOfNumbers > -1 ? @"(?=([^0-9]*?\d){" + MinNoOfNumbers.ToString() + ",})" : "")
+ (MinNoOfUniCaseChars > -1 ? "(?=([^" + Unicase + @"]*?[" + Unicase + @"]){" + MinNoOfUniCaseChars.ToString() + @",})" : "")
+ (MinNoOfLowerCaseChars > -1 ? "(?=([^" + Lowercase + @"]*?[" + Lowercase + @"]){" + MinNoOfLowerCaseChars.ToString() + ",})" : "")
+ (MinNoOfUpperCaseChars > -1 ? "(?=([^" + Unicase + @"]*?[" + Unicase + @"]){" + MinNoOfUpperCaseChars.ToString() + @",})" : "")
+ (MinNoOfSymbols > -1 ? "(?=([" + Unicase + Lowercase + @"0-9]*?[^" + Unicase + Lowercase + @"]){" + MinNoOfSymbols.ToString() + ",})" : "")
+ (DisallowedChars.Length > 0 ? @"(?=[^" + DisallowedChars + @"]+$)" : "")
+ @".*$";
}
This Expression validates the password entered by the user.
Concepts of
- Character sets (Unicode too)
- Look ahead (positive/negative)
- Grouping
- Back references
- Lazy/Greedy matches
are used in the Regular Expression.
The properties of the PasswordPolicy/Strength classes can be set from a database or other data source too.
The Validator has been tested for ASP .NET MVC 2 IE 7 and Firefox 3.6.8.
Sample usage
Add a reference to Toolkit.Web.Mvc.dll.
Copy the PasswordPolicyValidator.js (distributed along with the source code) to any location in the MVC project.
On the View page
<%@ Import Namespace="Toolkit.Web.Mvc" %>
<%@ Import Namespace="Toolkit.Security" %>
<script src="/Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script src="/Scripts/jquery.validate.js" type="text/javascript"></script>
<%
PasswordStrength Strength = new PasswordStrength{
StrengthCategories="weak,medium,strong",
StrengthColours="red,magenta,green",
MinPasswordLengthStrength="5,8,11",
MinNoOfLowerCaseCharsStrength="3,5,7",
MinNoOfUpperCaseCharsStrength="2,3,4",
MaxNoOfAllowedRepetitionsStrength="3,2,1"
};
PasswordPolicy Policy = new PasswordPolicy {
MinPasswordLength = 5,
MinNoOfLowerCaseChars = 3,
MinNoOfUpperCaseChars = 2,
MaxNoOfAllowedRepetitions=3
};
%>
<%= Html.TextBoxFor(m => m.UserName) %>
<%= Html.PasswordFor(m => m.Password) %>
<%= Html.ValidationMessageFor(m => m.Password) %>
<%= Html.PasswordPolicyValidatorFor(m => m.Password, Policy, "UserName", Strength, "../../Scripts/PasswordPolicyValidator.js", "* Password policy did not match!") %>
Sample Screenshots