Password Policy/Strength ASP.NET MVC Validator

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.

Passwords

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

Password policy not match


Similar Articles