【问题标题】:Issue in encoding password with spring security使用弹簧安全编码密码的问题
【发布时间】:2013-10-30 04:03:09
【问题描述】:

我正在使用 grails 2.3.0 并且在使用 spring security 对密码进行编码时遇到了奇怪的问题:

这是我的密码编码方法:

String encodePassword(String password) {
    return springSecurityService.encodePassword(password)
}

这样使用

log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")

我多次对同一个密码进行编码,每次都得到不同的编码密码。

日志:

$2a$10$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K
$2a$10$a7qybaiLF/eNrTSwFohjkezNaJTTDdMEinRYKjxDzEt.OoxaIgFOu
$2a$10$nZVhUT0QTmmbtt22CPtM..cLxU252RGBIMkd5aSd2AFXNTNLQ./6u

【问题讨论】:

    标签: grails spring-security


    【解决方案1】:

    没关系。看起来您正在使用 BCrypt 密码哈希,每次您对密码进行编码时,此算法都会使用随机盐(其他哈希算法使用“盐源属性”,如 id)。这种盐是预先散列的

    所以你有:

    • $2a - 盐版
    • $10 - 回合
    • $h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K - 用于 salt+hash 的 Base64,其中 salt 获取前 24 个字符,hash 获取其余字符:
      • h8T4BxgOeozmH/VSPJl7NeTaF - 盐
      • 2P0iONpSdqDN7dDFFAG.sy8WG/8K - 哈希(盐 + 密码 10 轮)

    查看 Spring Security 的 BCrypt 来源:https://github.com/spring-projects/spring-security/blob/master/crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java

    如果您需要手动检查用户密码,您必须使用passwordEncoder,例如:

    //dependency injection
    def passwordEncoder
    
    //validate
    String enteredPassword = params.password
    User user = ...
    if (!passwordEncoder.isPasswordValid(user.password, enteredPassword, null)) { //validates raw password against hashed
       //... wrong password entered
    }
    

    【讨论】:

    • 为什么要这样做?对密码进行哈希处理并且您可以登录还不够吗?
    • 我正在实现密码重置功能,我需要使用用户输入的当前密码检查我当前保存的密码。
    • 感谢@Igor 和@Burt。 passwordEncoder.matches 在我的情况下不起作用(我已经注入了 passwordEncoder bean),可能是我做错了什么。 passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) 给了我想要的结果。
    • 抱歉,刚刚发现 matches 来自 SS 版本 3.1。该插件使用 SS 3.0。顺便说一句,passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) 不能与存储的密码进行比较,也许你的意思是 passwordEncoder.isPasswordValid(user.password, 'mkb', null)
    • 是的,你是对的,我的意思是passwordEncoder.isPasswordValid(user.password, 'mkb', null)passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) 仅用于测试。再次感谢。
    【解决方案2】:

    Grails spring security 描述了更新密码的过程:https://grails-plugins.github.io/grails-spring-security-core/4.0.x/index.html

        User user = User.findByUsername(username)
       if (!passwordEncoder.matches(password, user.password)) {
          flash.message = 'Current password is incorrect'
          render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
          return
       }
    
       if (passwordEncoder.matches(password_new, user.password)) {
          flash.message = 'Please choose a different password from your current one'
          render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
          return
       }
    

    其中 password 或 new_password 是参数或方法参数

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 1970-01-01
      • 2012-04-21
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多