Table of Contents
Recently, I had the opportunity to review the ASP.NET - Password Strength Indicator using jQuery and XML plugin and make some enhancement to it. Here is the summary of the changes.
As mentioned in the previous article, the purpose of the plugin is to provide guidance to a user to choose a strong password. I wanted 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 Nonalphanumeric characters (special characters such as: ! @ # …)
- Check if password meets 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 character (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:
- Review the element in the PasswordPolicy.xml
- Review the logic to check for keyboard/character sequences
- How to create and publish the NuGet package
- How to consume the package
Shown in table 1 is the list of XML node and its corresponding description:
Node | Description |
duration | This 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 |
minLength | The password minimum acceptable length |
maxLength | The password maximum acceptable length |
numsLength | The minimum number of required digits (0-9) |
upperLength | The minimum number of required upper case (A-Z) |
specialLength | The minimum number of required special characters |
barWidth | Specify the width of the bar indicator [Example: 100, 200] |
barColor | Specify the final color of the bar [Example: Yellow, Maroon, etc.…] |
specialChars | The allowable valid special characters |
useMultipleColors | Turn on/off multiple colors [red, blue, green]. 1=Yes, 0=No |
maxConsecutiveRepeatedChars | 0 = 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
|
maxKeyboardSequence | Specify 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). |
keyboardSequenceCharacters | Specify 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 |
Table 1
Shown in listing 1 and 2 are the server and client side validation code 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 password string entered by the user to find if any part of the string
is a 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 allow…" on the client side. As mentioned earlier, please feel free to enter any string that you would consider a sequence under the KeyboardSequenceCharacters
value.
public static bool IsPasswordContainSequence
(string strPassword, PasswordSetting passwordSetting)
{
int startIndex = 0;
int num = 0;
int length = passwordSetting.MaxKeyboardSequence + 1;
string empty = string.Empty;
string str1 = passwordSetting.KeyboardSequenceCharacters;
while (num < strPassword.Length)
{
num = startIndex + length;
string str2 = strPassword.ToLower().Substring(startIndex, length);
if (str1.Contains(str2))
return true;
++startIndex;
}
return false;
}
Listing 1
this.getKeyboardSequenceChar = function (passwordVal) {
var maxQwertySequence = password_settings.maxKeyboardSequence + 1;
var keyboardSequenceCharacters =
password_settings.keyboardSequenceCharacters;
var num = 0;
var startIndex = 0;
if (passwordVal.length >= maxQwertySequence) {
while (num < passwordVal.length) {
num = startIndex + maxQwertySequence;
var lastXsubString =
passwordVal.substr(startIndex, maxQwertySequence);
if (keyboardSequenceCharacters.indexOf
(lastXsubString.toLowerCase()) >= 0) {
return lastXsubString;
}
startIndex++;
}
}
Listing 2
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.
Figure 2
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.
Figure 3
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.
="1.0"
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings xdt:Transform="InsertIfMissing">
<add key="passwordPolicyXMLLocation" value="~/MyXML/PasswordPolicy.xml"
xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
</appSettings>
</configuration>
Listing 3
="1.0"
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="passwordPolicyXMLLocation"
xdt:Transform="Remove" xdt:Locator="Match(key)" />
</appSettings>
</configuration>
Listing 4
Right click the project and select properties to update package properties. Here, you can specify the Package ID, Package Version, project URL, 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 updating 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.
Figure 4
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.
Figure 5
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.
Figure 6
Once we have verified the package 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.
From the menu, click on Tools
, NuGet Package Manager, Manage NuGet Packages for Solution…. Make sure the package source is pointing to nugget.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.
Figure 7
Once the package 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.
Here are the steps to install the package to the ASP.NET application/project or other framework such as Classic ASP/PHP, etc. without using NuGet Manager.
- Download and extract the NuGet package
- Please note that this plugin requires jQuery 1.3+
- Navigate to the Content folder and copy the MyXML, PasswordStrengthIndicator.Example and Scripts folder into the application solution
- Add the below key to
appSettings
in the web.config (not applicable to other Framework)
< key="passwordPolicyXMLLocation" value="~/MyXML/PasswordPolicy.xml" />
- Add the reference lib/PasswordStrengthIndicator.Core.dll to the project (not applicable to other Framework)
- For other application framework, you need to write your own server-side validation, refer to the
PasswordStrengthIndicator.Core
source code. - Likewise, you can download the source/sample code from the repository and study the project structure.
I hope someone will find this information useful and make your 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 contact me if you want to help improve this article. Please use the following link to report any issues https://github.com/bryiantan/PasswordStrengthIndicator/issues.
Tested on: Internet Explorer 11,10,9.0, Firefox 50, Google Chrome 25.0 and Apple Safari 5.1.7
- 26th December, 2016 - Initial version
- 3rd January, 2017 - Added Install Nuget Package without NugGet Package Manager
- 11th January, 2017 - Updated Install Nuget Package without NugGet Package Manager
- 20th February, 2017 - Updated contents/languages