Problem:
I've recently upgraded to use the latest spring security plugin version 1.2.7.3.
After running s2-quickstart command as suggested in the documentation, the User, Role and UserRole domain objects were created.
I wanted to prepopulate the database with a default user by adding the following in Bootstrap.groovy:
Bootstrap.groovy
def init = { servletContext ->
User existingUser = User.findByUsername('bob')
if (existingUser == null) {
User u = new User(username: 'bob', enabled: true, password: 'password')
boolean saved = u.save(flush:true)
}
}
I started up the application and tried to login.
However when I try to authenticate I got a BadCredentialsException:
Investigation:
After a few hours of debugging, I noticed the way in which passwords were encoded have changed.
In the User domain class we see the following methods:
User.groovy
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
As you can see, immediately before the User object is inserted to the database it will replace the password with an encoded password.
I decided to log how the password was being encoded by modifying the encodePassword method as follows:
protected void encodePassword() {
System.out.println("encoding password: "+password)
password = springSecurityService.encodePassword(password)
System.out.println("to "+this.password)
}
After running the application, I could see that the encodePassword method was being called twice!! In other words, it was re-encoding an already encoded password. Hence when I try to login I get the BadCredentialsException.