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?
 
    