How to Customize Password Validation
On this page
The Curity Identity Server does not have password strength validation active by default for creating new accounts using the registration feature of the HTML Form
authenticator. This article covers how to enable password validation using a Validation Procedure
. It also shows how to update the frontend with a strength indicator while typing a password.
The policy that will be enforced requires four out of these five criteria to be true. A password should:
- have the minimum length of eight (8) characters
- have at least one lower case character
- have at least one upper case character
- have at least two digits
- have at least one special character
Prerequisites
You will need an installation of the Curity Identity Server with the basic setup completed. Follow the Getting Started Guides to achieve this. Alternatively, if you have a system up and running with your own configuration, you can use that as well. Just be aware that you probably have different names for certain components.
Enabling Backend Validation
The Curity Identity Server uses Validation Procedures
for input validation. Validation procedures can be used for many purposes but are typically added during authentication or registration. A procedure is written in JavaScript.
Create Validation Procedure
Create a procedure by using the Admin UI. Click on System->Procedure->New procedure.
Give it the name password-strength
and make sure the type is validation-procedure
.
Insert the following code:
function result(validationContext) {var errors = {};var password = validationContext.request.getFormParameter("password");if (checkStrength(password) < 4) {errors.strength = "weakpassword";}return errors;}function checkStrength(enteredPassword) {var length = /(.{8,})/;var upperCase = /(.*[A-Z])/;var lowerCase = /(.*[a-z])/;var digit = /(.*[0-9].*[0-9])/;var specialChar = /([^A-Za-z0-9])/;var points = 0;if (length.test(enteredPassword)) {points++;}if (upperCase.test(enteredPassword)) {points++;}if (lowerCase.test(enteredPassword)) {points++}if (digit.test(enteredPassword)) {points++;}if (specialChar.test(enteredPassword)) {points++;}return points;}
The result()
function will be called with a context once the procedure is executed. A validation is considered successful if there are no errors returned. An error returned refers to a message key
, in this case, weakpassword
. This key is used to present a localized error message which will be declared later.
Assigning the Validation Procedure
Assign the validation procedure to an authenticator to activate password validation during account registration. Click on Authenticators and select the authenticator to update; in this example, username-password. Expand the Advanced configuration section. Under Request Validation, click on Add and enter the following values:
Request Subpath | Endpoint | HTTP Method | Validation Procedure |
---|---|---|---|
index | authentication-service-registration | post | password-strength |
The password-strength
validation procedure will get executed when an HTTP POST
request receives the registration
endpoint through the username-password
authenticator.
Add a New Message
The frontend will display the message corresponding to the message key sent by the validation procedure. Since weakpassword
is a new key, the message for each supported language has to be updated. In this example, only English will be updated.
To add a new message, copy the existing messages into the overrides
directory.
cp $IDSVR_HOME/usr/share/messages/core/en/messages \$IDSVR_HOME/usr/share/messages/overrides/en/
Then open $IDSVR_HOME/usr/share/messages/overrides/en/messages
and add:
authenticator.html-form.create-account.weakpassword=Password is not complex enough
Update Frontend
With the backend in place, it is only possible to set a password that meets the requirements. Otherwise, the backend throws an error.
The standard registration page already has a progress bar showing password strength, but it does not match the new policy of the validation procedure. This section describes how to control that progress bar and add an extra checkmark when the password is strong enough.
Create a fragment
called password-ok.vm
in the overrides/fragments
directory.
mkdir $IDSVR_HOME/usr/share/templates/overrides/fragmentstouch $IDSVR_HOME/usr/share/templates/overrides/fragments/password-ok.vm
In that file, add the following content:
<style $!nonceAttr>.password-group-ok {position: relative;}.password-group-ok .progress {width: calc(100% - 28px);}.password-group-ok::after {content: '\f120';font-family: 'Ionicons';color: #57C75C;font-size: 1rem;width: 18px;height: 18px;position: absolute;right: 0;bottom: -4px;z-index: 1;}</style>#parse("fragments/jquery")<script $!nonceAttr>$(window).on('load', () => {var passwordField = $("input[type='password']");passwordField.off();passwordField.on("input", passwordValidation)});function passwordValidation() {var passwordField = $("input[type='password']");var strength = checkStrength(passwordField.val());setBar(strength);}function checkStrength(enteredPassword) {var length = /(.{8,})/;var upperCase = /(.*[A-Z])/;var lowerCase = /(.*[a-z])/;var digit = /(.*[0-9].*[0-9])/;var specialChar = /([^A-Za-z0-9])/;var points = 0;if (length.test(enteredPassword)) {points++;}if (upperCase.test(enteredPassword)) {points++;}if (lowerCase.test(enteredPassword)) {points++}if (digit.test(enteredPassword)) {points++;}if (specialChar.test(enteredPassword)) {points++;}return points;}function setBar(value) {var allColors = ("progress-success progress-info progress-warning progress-danger");var bar = $("div.progress div[role='progressbar']");var passwordGroup = $("div.password-group");bar.removeClass(allColors);passwordGroup.removeClass("password-group-ok");value *= 20;if (value < 33) {bar.addClass("progress-danger");}else if (value < 66) {bar.addClass("progress-warning");}else {bar.addClass("progress-success");passwordGroup.addClass("password-group-ok");}bar.width(value + "%");}</script>
This fragment contains everything needed, both CSS and JavaScript. The CSS is to create a green checkmark once the password is strong enough. The JavaScript takes care of overriding the progress bar's existing functionality and applying the new policy to it.
Reuse of code
Notice how checkStrength()
is reused from the Validation Procedure
.
Include this fragment into the registration template of the HTML form authenticator.
Create a folder structure and copy the original template to the overrides
folder.
mkdir -p $IDSVR_HOME/usr/share/templates/overrides/authenticator/html-form/create-account/cp $IDSVR_HOME/usr/share/templates/core/authenticator/html-form/create-account/get.vm \$IDSVR_HOME/usr/share/templates/overrides/authenticator/html-form/create-account/
Open get.vm
in the overrides
folder and add the fragment before the form
element.
#define($_body)#parse("fragments/password-ok")<form method="post" class="login-form">
Try It Out
With both the frontend and backend in place, you can now try out the validation procedure. Click on Create Account when using the username-password
authenticator. Observe how the progress bar changes when entering a password. When the password is strong enough, the bar turns green, and the checkmark appears. If you choose to create an account with a weak password, the backend will return an error indicating that the password is not complex enough.
Upgrade
When the Curity Identity Server is upgraded, the files in the overrides
folder are copied into the new system directly or added to a custom Docker image. The validation procedure is included in the backed-up configuration data. This makes it straightforward to maintain custom logic over time.
Conclusion
This tutorial covered how to use a custom validation procedure for password validation, but a validation procedure can validate any input. For example, the procedure could check that the user agrees to the terms when creating an account.
The updated UI will indicate when a password is strong, but it does not prevent the user from trying to create an account with a weak password. This could be changed for a better user experience by disabling buttons, for example.
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial