
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: February 4, 2020
In this quick tutorial, we’ll look at how to implement and show proper password constraints during registration. Things like – the password should contain a special character, or it should be at least 8 characters long.
We want to be able to use powerful password rules – but we don’t want to actually implement these rules manually. So, we’re going to make good use of the mature Passay library.
First – let’s create a custom constraint ValidPassword:
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ TYPE, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface ValidPassword {
String message() default "Invalid Password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
And use it in the UserDto:
@ValidPassword
private String password;
Now – let’s use the library to create some powerful password rules without having to actually manually implement any of them.
We’ll create the password validator PasswordConstraintValidator – and we’ll define the rules for the password:
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
@Override
public void initialize(ValidPassword arg0) {
}
@Override
public boolean isValid(String password, ConstraintValidatorContext context) {
PasswordValidator validator = new PasswordValidator(Arrays.asList(
new LengthRule(8, 30),
new UppercaseCharacterRule(1),
new DigitCharacterRule(1),
new SpecialCharacterRule(1),
new NumericalSequenceRule(3,false),
new AlphabeticalSequenceRule(3,false),
new QwertySequenceRule(3,false),
new WhitespaceRule()));
RuleResult result = validator.validate(new PasswordData(password));
if (result.isValid()) {
return true;
}
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(
Joiner.on(",").join(validator.getMessages(result)))
.addConstraintViolation();
return false;
}
}
Notice how we’re creating the new constraint violation here and disabling the default one as well – in case the password is not valid.
Finally, let’s also add the Passay library into our pom:
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>1.0</version>
</dependency>
For a bit of historical info, Passay is the descendant of the venerable vt-password Java library.
Now that the server side is done, let’s take a look at the client side and implement a simple “Password Strength” functionality with JavaScript.
We’ll use a simple jQuery plugin – jQuery Password Strength Meter for Twitter Bootstrap – to show the password strength in registration.html:
<input id="password" name="password" type="password"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="pwstrength.js"></script>
<script type="text/javascript">
$(document).ready(function () {
options = {
common: {minChar:8},
ui: {
showVerdictsInsideProgressBar:true,
showErrors:true,
errorMessages:{
wordLength: '<spring:message code="error.wordLength"/>',
wordNotEmail: '<spring:message code="error.wordNotEmail"/>',
wordSequences: '<spring:message code="error.wordSequences"/>',
wordLowercase: '<spring:message code="error.wordLowercase"/>',
wordUppercase: '<spring:message code="error.wordUppercase"/>',
wordOneNumber: '<spring:message code="error.wordOneNumber"/>',
wordOneSpecialChar: '<spring:message code="error.wordOneSpecialChar"/>'
}
}
};
$('#password').pwstrength(options);
});
</script>
And that’s it – a simple but very useful way to show the strength of the password on the client side and enforce certain password rules on the server side.