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 ErrorMessage 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.

MvcClasses.jpg

The PasswordPolicy properties are
 
  

Property

Explanation

Accepted values

UnicodeCharSetRanges

Ranges of Unicode character sets. Validator defaults to English if property 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 password. This property is to be used by Unicase languages.

0 or greater

MinNoOfLowerCaseChars

Minimum number of lower case 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 password

0 or greater

DisallowedChars

Characters not allowed in password

Empty or list of characters

UserNameControlID

Specified to confirm that user name (case insensitive) is not part of password

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 colours (supported in javascript) for the corresponding strength categories

Comma separated list of strength category colours

UnicodeCharSetRanges

Ranges of Unicode character sets. Validator defaults to English if property 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 for strength categories

Empty or comma separated list of positive integer values


Policy

Policy properties are those that the password MUST confirm 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 less lower case chars in password is weak, 6 - 5 is medium and 7 or more is strong.

The Strength and Policy can be used independent 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 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, 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 Japanese Hiragana range.

UnicodeCharSetRanges = "\u3040-\u309F"

More information on Unicode character set ranges can be found in 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 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 submit. 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 by 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 does the validation of the password entered by the user.

Concepts of
  • Character sets (Unicode too)
  • Look ahead (positive/negative)
  • Grouping
  • Back references
  • Lazy/Greedy match

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 and 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.

In 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

image1.gif

erver'>
Next Recommended Readings