Password Strength Indicator With NuGet Package



Introduction


Recently, I had the opportunity to review the plugin and make some enhancements to it. Here is the summary of the changes.

  • Updated the plugin to check for keyboard/character sequences (i.e., 123456, qwerty, …)
  • Added sample code using MVC5
  • Added the projects to GitHub (https//github.com/bryiantan/PasswordStrengthIndicator)
  • Added the plugin to NuGet (https//www.nuget.org/packages/PasswordStrengthIndicator/)
  • Fixed minor bugs

The purpose of this plugin is to provide guidance to the user to choose a strong password. I want to reiterate that the plugin provides the following validation on client and server side

  • Check if password contains x number of required uppercase characters (A-Z)
  • Check if password contains any lowercase characters (a-z)
  • Check if password contains x number of required base 10 digits (0 through 9)
  • Check if password contains x number of required allowable non-alphanumeric characters (special characters such as ! @ # …)
  • Check if password meet the minimum and maximum password length requirement
  • Check if password exceeded the allowable maximum consecutive repeated character
  • Check if password contains keyboard character sequences specified in the XML file

You need to write additional code/logic if you want to add functionality to perform the following.

  • Prevent user from using previous x history password
  • Password maximum age
  • Prevent user from entering common characters (i.e, Apple, Chicken, ...) (I think you can include that under the keyboardSequenceCharacters Node, but that will be too overwhelming)
  • etc…

In this article, please allow me to share with everyone the following items

  • A review of the element in the PasswordPolicy.xml
  • A review of the logic to check for keyboard/character sequences
  • How I created and published the NuGet package
  • How to consume the package

What is the PasswordPolicy.xml?

Shown in table 1 is the list of xml node and its corresponding description.

NodeDescription
durationThis is just an example. You can add a node and value in the XML file and then add the business logic to the PasswordStrengthIndicator.Core class
minLengthThe password minimum acceptable length
maxLengthThe password maximum acceptable length
numsLengthThe minimum number of required digits (0-9)
upperLengthThe minimum number of required upper case (A-Z)
specialLengthThe minimum number of required special characters
barWidthSpecify the width of the bar indicator [Example: 100, 200]
barColorSpecify the final color of the bar [Example: Yellow, Maroon, etc.…]
specialCharsThe allowable valid special characters
useMultipleColorsTurn on/off multiple colors [red, blue, green]. 1=Yes, 0=No
maxConsecutiveRepeatedChars0 = Allow repeat, no validation. [example: aaaaaaaaA will be valid]
1 and above = Specify maximum number of successive repetitions of a given character.

Example
  • if 1, aa will not be valid because it repeated more than 1 time
  • if 2, aaa will not be valid because it repeated more than 2 times
maxKeyboardSequenceSpecify the maximum allowable keyboard/character sequence.

Example
  • if 2, 123 will not be valid, but 12 will be valid.
  • If 3, qwer159 will not be valid, but qwe159 will be valid
Note: The sequence is defined in keyboardSequenceCharacters node)
keyboardSequenceCharactersSpecify the keyboard/characters’ sequence. The node name could be a little misleading depending on the type of keyboard you’re using. You can be creative here and specify anything that you would consider a sequence in one string. Example: abcdefghijklmnopqrstuvwxyzzyxwvuts…123456...

Note: Not case sensitive

Logic to check for keyboard/character sequences


Shown in listing 1 and 2 are the server and client side validation codes respectively. First, the code will retrieve the maximum character sequence (MaxKeyboardSequence) and sequence characters (KeyboardSequenceCharacters) from the PasswordPolicy.xml file. Then, it will loop through the string/password entered by the user to find if any part of the string is subset of the string defined in KeyboardSequenceCharacters.

Here is an example. Let's say, a user entered Nin@Abc357, MaxKeyboardSequence and KeyboardSequenceCharacters was set to 2 and abcdefghijklmnopqrstuvwxyzzyxwvuts respectively. Initially, the logic will check if KeyboardSequenceCharacters contains Nin. Then, it will check if it contains in@, n@A, @Ab, Abc and so forth. If the KeyboardSequenceCharacters was set to 3, then the validation check will begin with Nin@, in@A, n@Ab and so on. Based on the example, part of the password entered (Nin@Abc357) was a subset of KeyboardSequenceCharacters. Thus, user will receive a validation error like "Keyboard sequence character not allowed…" on the client side. As mentioned earlier, please feel free to enter any string that you would consider a sequence under the KeyboardSequenceCharacters value.

Listing 1

  1. public static bool IsPasswordContainSequence(string strPassword, PasswordSetting passwordSetting) {  
  2.     int startIndex = 0;  
  3.     int num = 0;  
  4.     int length = passwordSetting.MaxKeyboardSequence + 1;  
  5.     string empty = string.Empty;  
  6.     string str1 = passwordSetting.KeyboardSequenceCharacters;  
  7.     while (num < strPassword.Length) {  
  8.         num = startIndex + length;  
  9.         string str2 = strPassword.ToLower().Substring(startIndex, length);  
  10.         if (str1.Contains(str2)) return true;  
  11.         ++startIndex;  
  12.     }  
  13.     return false;  
  14. }  
Listing 2
  1. this.getKeyboardSequenceChar = function(passwordVal) {  
  2.         var maxQwertySequence = password_settings.maxKeyboardSequence + 1;  
  3.         var keyboardSequenceCharacters = password_settings.keyboardSequenceCharacters;  
  4.         var num = 0;  
  5.         var startIndex = 0;  
  6.         if (passwordVal.length >= maxQwertySequence) {  
  7.             while (num < passwordVal.length) {  
  8.                 num = startIndex + maxQwertySequence;  
  9.                 var lastXsubString = passwordVal.substr(startIndex, maxQwertySequence);  
  10.                 if (keyboardSequenceCharacters.indexOf(lastXsubString.toLowerCase()) >= 0) {  
  11.                     return lastXsubString;  
  12.                 }  
  13.                 startIndex++;  
  14.             }  
  15.         }  

How to create the NuGet package?

The very first step is to download and install the NuGet Package Project extension from http//nuproj.net/.

After the installation, open the Visual Studio IDE, navigate to File >> New >> Project and select NuGet under installed templates, Refer to figure 1.



Add two folders into the project, namely content and lib. We can do this by right clicking the project, selecting add and then selecting new folder. I'll add the JavaScript, XML file and sample page into the content folder. The files in the content folder will be added into the target solution during the installation. Now, I want the PasswordStrengthIndicator.Core.dll to be added to the target reference during the installation. In order to do this, I will add the PasswordStrengthIndicator.Core.dll assembly into the lib folder. Next, I'll add web.config.install.xdt and web.config.uninstall.xdt into the Content folder. The purpose of these two files is to add and remove a key into/from the web.config appSettings section during package installation and uninstallation. At this point the solution should look like figure 3.



What is the web.config.install.xdt and web.config.uninstall.xdt file?

Shown in listing 3 and listing 4 are the contents of the web.config.install.xdt and web.config.uninstall.xdt respectively. During the package installation, the NuGet will check if appSettings element exists, if not, insert the element. Then, it will check if the passwordPolicyXMLLocation key needs to be inserted into the web.config file. In order to avoid complication, the passwordPolicyXMLLocation key will be removed from the web.config during package uninstallation and not the entire appSettings element.

Listing 3
  1. <?xml version="1.0" ?>  
  2. <configuration xmlnsxdt="http//schemas.microsoft.com/XML-Document-Transform">  
  3.     <appSettings xdtTransform="InsertIfMissing">  
  4.         <add key="passwordPolicyXMLLocation" value="~/MyXML/PasswordPolicy.xml" xdtLocator="Match(key)" xdtTransform="InsertIfMissing" /> </appSettings>  
  5. </configuration>  
Listing 4
  1. <?xml version="1.0" ?>  
  2. <configuration xmlnsxdt="http//schemas.microsoft.com/XML-Document-Transform">  
  3.     <appSettings>  
  4.         <add key="passwordPolicyXMLLocation" xdtTransform="Remove" xdtLocator="Match(key)" /> </appSettings>  
  5. </configuration>  
Package Setting

Right click the project and select properties to update package properties. Here you can specify the Package ID, Package Version, project URL, and provide a summary and description of the package, license URL, etc. The package name is the combination of Package ID and Package Version. In this example, the package name will end up like NuGetPackage1.1.0.0.nupkg. So, don't forget to update the Package Version each time you update the package. The nuget.org will not allow you to publish a package with the same name twice. You also can utilize the Readme.txt file to include more information about the package.



How to test the package before publishing it? Let start by opening a current web project or create a new web project. Go to Tools, NuGet Package Manager, Package Manager Settings. Click on the Package Sources, add (green plus sign) then click on the eclipse (…) to browse to the package location. After that, click on the Update button. Refer to figure 5 as an example.



Now, let's go back to Tools, NuGet Package Manager, Manage NuGet Packages for Solution…. Change the package source to the name specified in figure 5 and click on Browse. Select the package and the project and then click on the Install button. Refer to figure 6.



How to publish the package?

Once we have verified the package has been installed/uninstalled correctly, navigate to https//www.nuget.org >> login >> create an account if you don’t have one. Click on the Upload Package menu item. Then, click on browse and navigate to the package location. In our example, the package name is NuGetPackage1.1.0.0.nupkg. Follow the instruction on the screen to complete the process.

How to install the PasswordStrengthIndicator NuGet Package?

From the menu, click on Tools >> NuGet Package Manager >> Manage NuGet Packages for Solution…. Make sure the package source is pointing to nuget.org. Click on Browse and search for PasswordStrengthIndicator or Bryian Tan. You should see the result similar to figure 7. Choose the project you want to install this package to and then click on the "Install" button.



Once the package is installed successfully, the readme.txt will open up. You can go over it to learn more about the plugin. The following items should be in your project solution.
  • MyXML folder which contains PasswordPolicy.xml and PasswordPolicy.xslt files
  • PasswordStrengthIndicator.Example which contains Default.aspx.txt and jQuery_Password_Strength_Indicator.htm files
  • Under the Scripts, you should see jquery.password-strength-2.0.min.js and jquery.blockUI.js
  • You should see PasswordStrengthIndicator.Core being referenced by the project
  • passwordPolicyXMLLocation key is being added into the appSettings section in the web.config

To run the test, open up the jQuery_Password_Strength_Indicator.htm file and update the jQuery reference. Rename the Default.aspx.txt to Default.aspx and update the jQuery reference.

How to Install PasswordStrengthIndicator  package without NuGet Package Manager?

Here are the steps to install the package to the ASP.NET application/project without NuGet Manager.

  1. Download and extract the NuGet package
  2. Please note that this plugin requires jQuery 1.3+
  3. Navigate to the Content folder and copy the MyXML, PasswordStrengthIndicator.Example and Scripts folder into the application solution
  4. Add the below key to appSettings in the web.config
    < key="passwordPolicyXMLLocation" value="~/MyXML/PasswordPolicy.xml" />
  5. Add the reference lib/PasswordStrengthIndicator.Core.dll to the project
  6. For other application framework, you need to write your own server-side validation, refer to the PasswordStrengthIndicator.Core source code.
  7. You can also download the source code/sample from the repository and study the structure of the project.
Conclusion

I hope someone will find this information useful to make their programming job easier. If you find any bugs or disagree with the contents or want to help improve this article, please drop me a line and I'll work with you to correct it. I would suggest downloading the demo and exploring it in order to grasp the full concept because I might miss some important information in this article. Please send me an email if you want to help improve this article. Please use the following link to report any issues


Similar Articles