I'm trying to use the BCrypt password hashing in my Grails app that's using the Spring Security plugin. I've enabled BCrypt by adding the following to Config.groovy
grails.plugins.springsecurity.password.algorithm = 'bcrypt'
And I've defined the following codec to simplify using BCrypt to encode paswords:
public class PasswordCodec {
// it doesn't seem to be possible to dependency-inject codecs, so lookup the bean ourselves
@Lazy
private static PasswordEncoder passwordEncoder = Holders.grailsApplication.mainContext.getBean('passwordEncoder')
static encode = { str ->
passwordEncoder.encodePassword(str.toString(), null)
}
}
When I start the application in dev mode the database is bootstrapped with a few accounts (each of which has the same password, e.g.
3.times { i ->
def username = "user$i"
def password = "secret".encodeAsPassword()
new User(username: username, password: password).save()
// also assign the user a role
}
If I look in the database, I see that the encoded value of each of these user's password is different! So it's no surprise that when a user attempts to login and enters a password of "secret", the BCrypt-encoded password value doesn't match what's saved in the database, because it seems that the BCrypt-encoded value of a String somehow changes over time.
Obviously I'm doing something wrong here, but I've no idea what?