3

我的网络应用程序使用 Spring Security 插件进行身份验证和授权。我正在构建某种 API,我需要在其中验证用户密码。

Spring Security 配置为使用具有 5 个 logrounds 和username属性作为 salt 的 BCrypt:

grails.plugins.springsecurity.password.algorithm = 'brcypt' 
grails.plugins.springsecurity.password.bcrypt.logrounds = 5
grails.plugins.springsecurity.dao.reflectionSaltSourceProperty = 'username' // password salting

现在,在我的控制器中,我想验证用户密码并登录。为此,我打电话给springSecurityService.encodePassword(cmd.password, cmd.username)

cmd我的参数的命令对象在哪里。问题是,在每个请求中,编码springSecurityService的密码都与数据库中的用户密码不同,而且永远不会相同。我也尝试在encodePassword调用中使用常量值,如下所示: springSecurityService.encodePassword('foo', 'bar')结果是相同的:每个请求编码的密码都不同。这样我就无法验证用户密码并从数据库中获取有效的用户实例。

任何想法如何解决这个问题?

4

1 回答 1

6

bcrypt每次生成一个 uniq salt,并将其包含在结果哈希中。因为它springSecurityService.encodePasswod只是忽略了第二个参数,以及reflectionSaltSourceProperty选项(参见来源)。因此,每次您都会为相同的输入数据获得不同的哈希值。

您可以使用BCrypt类来验证密码,例如:

if (BCrypt.checkpw(candidate_password, stored_hash))
    System.out.println("It matches");
else
    System.out.println("It does not match");

请参阅 BCrypt 的文档:http: //static.springsource.org/autorepo/docs/spring-security/3.1.x/apidocs/org/springframework/security/crypto/bcrypt/BCrypt.html

顺便说一句,当您使用 Spring Security 时,它已经在框架中实现,因此您可以使用passwordEncoderbean:

def passwrodEncoder
...
passwordEncoder.isPasswordValid(user.password, cmd.password, user.username) //user.username will be ignored
于 2013-06-26T11:17:30.440 回答