Monday 2 November 2009

Liferay Password Policies with a regular expression sauce

For a Liferay project that I'm working on there are a bunch of security requirements. One of those is that a user password has to conform to a certain set of rules. Because Liferay is pretty customizable, changing the password policy shouldn't be a problem.

Looking around the Control Board already reveals some possibilities hidden in the Portal > Password Policies menu. Here you can tweak the default password policy or even create a new one. There are several things to customize on this page:
  • Changeable/Change required: can the user change his/her password and is a change required after the first login
  • Password Syntax Checking: (dis)allow passwords that are common dictionary words and set a minimum password length
  • Password History: disallow passwords according to a password history of a configurable length
  • Password Expiration: how long is a password valid before it needs to be changed
  • Lockout: how many times can someone try to log in correctly before his/her account gets locked and how does it get unlocked
While this is already a nice feature set, the password syntax checking isn't quite enough to satisfy our password requirements. Checking the source code and the default portal.properties file reveals that it is possible configure a custom passwords.toolkit. This can be one you create yourself and that extends from com.liferay.portal.security.pwd.BasicToolkit:
public abstract class BasicToolkit {

public abstract String generate();

public void validate(String password1, String password2, PasswordPolicy passwordPolicy)
throws PortalException, SystemException {

validate(0, password1, password2, passwordPolicy);
}

public abstract void validate(long userId, String password1, String password2, PasswordPolicy passwordPolicy)
throws PortalException, SystemException;

}

Another possibility is to use the regular expression toolkit that is available in Liferay. This toolkit can be configured as follows:

#
# Input a class name that extends
# com.liferay.portal.security.pwd.BasicToolkit. This class will be called to
# generate and validate passwords.
#
passwords.toolkit=com.liferay.portal.security.pwd.RegExpToolkit

#
# If you choose to use com.liferay.portal.security.pwd.RegExpToolkit as
# your password toolkit, set the regular expression pattern that will be
# used to generate and validate passwords.
#
# Note that \ is replaced with \\ to work in Java.
#
# The pattern ensures that passwords must have at least 4 valid
# characters consisting of digits or letters.
#
passwords.regexptoolkit.pattern=(?=.{4})(?:[a-zA-Z0-9]*)
One useful regular expression (customized a bit more) that checks if a password is at least 6 characters long, contains at least 1 digit, 1 lowercase/uppercase character, 1 symbol from a given list and no whitespace is:

^.*(?=.{6,})(?=.*\d)(?=.*[a-zA-Z])(?=.*[@#$%^&+=])(?!.*\s).*$

I would be using this regular expression if I could only find out how to extend it so it checks if a passwords contains for example at least 3 lowercase/uppercase characters. I tried several variants, but didn't succeed. So for the moment I'm using a custom written BasicToolkit that is using plain old Java code to do the necessary checks.

If a tree falls in the woods does it make a sound? Can you merge a SVN branch if your mother hasn't told you about it?

1 comment:

  1. My big fat fingers hit the wrong button and deleted a comment instead of publishing it. So I'm adding this comment for user 'Auke':


    Without any testing I would guess it would be:

    ^.*(?=.{6,})(?=.*\d)(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*[@#$%^&+=])(?!.*\s).*$

    Maybe you can replace that with:

    ^.*(?=.{6,})(?=.*\d)(?=(.*[a-zA-Z]){3,})(?=.*[@#$%^&+=])(?!.*\s).*$

    To extend to 3 lowercase/uppercase letters.

    ReplyDelete