Vithun's Blog Notes on Software

Custom Password Encoder For Grails Spring-Security Plugin

The spring-security (core and others) plugin is very handy for incorporating user (and role) based functionalities for a grails application. The plugin comes with a lot of features out-of-the-box. And more often than not, some of the basic features can be used as is. However, there are occasions when a little bit of customization might be required.

In my current project, I was required to use a custom password encryption algorithm. The spring-security plugin uses the SHA-256 algorithm by default. This can be changed to use other standard algorithms (MD2, MD5 etc.) by adding the following lines (if, for example, MD5 encoding is required) in /grails-app/conf/Config.groovy:

grails.plugins.springsecurity.password.algorithm = "MD5"

But what I wanted was to use a custom algorithm of our own, not the standard ones. Fortunately, this is again, very easy. Because of Spring’s dependency injection, we can easily create our own password encoder and inject it. I have outlined how I did this below.

I first created a PasswordEncoder class which implemented Spring’s PasswordEncoder interface. I then overrode the methods of the interface according to our requirements.

class PasswordEncoder implements org.springframework.security.authentication.encoding.PasswordEncoder {

    @Override
    String encodePassword(String password, salt = null) {
        def encodedPassword
        /* TODO Encode the password using a custom algorithm */
        return encodedPassword
    }

    @Override
    public boolean isPasswordValid(String encodedPassword, 
        String rawPassword, salt = null) {
        return (encodedPassword == encodePassword(rawPassword, salt))
    }
}

Once this is done, I just injected the PasswordEncoder as a bean in the application context. In grails, this can be done by declaring the bean in /grails-app/conf/spring/resources.groovy:

beans = {
    passwordEncoder(packagename.PasswordEncoder)
}

And that’s it! The plugin will now use this custom password encoder for encryption.