spring security BCryptPasswordEncoder接入系统

通常情况下,在新系统中使用BCrypt加密不需要考虑太多,但老系统由于存在大量旧数据,
草率接入会导致老用户无法登录,这种情况该怎么解决?
很简单,我们自己实现一个PasswordEncoder 并继承BCrpytPasswordEncoder即可。

@Component
public class MyPasswordEncoder extends BCryptPasswordEncoder {

    private final Log logger = LogFactory.getLog(this.getClass());

    // BCrypt 密文的正则表达式
    private Pattern BCRYPT_PATTERN = Pattern.compile("\\A\\$2(a|y|b)?\\$(\\d\\d)\\$[./0-9A-Za-z]{53}");

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        if (rawPassword == null) {
            throw new IllegalArgumentException("rawPassword cannot be null");
        } else if (encodedPassword != null && encodedPassword.length() != 0) {
            if (!this.BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
                // TODO 如果密码不是BCrypt 密文 do something
                return ...;
            } else {
                return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
            }
        } else {
            this.logger.warn("Empty encoded password");
            return false;
        }
    }
}

在这个PasswordEncoder中,只有当密码不是BCrypt密文时,才启用自定义的匹配逻辑,
其余还是沿用原来的方案,即可轻松达到兼容的目的。
再进一步,如果我们不仅想要兼容,还想将不安全的旧密码无缝修改成BCrypt密文,该如何操作呢?这是个很好的问题。
如果旧密码都是未经任何加密的明文,也许“跑库”修改是非常好的一种选择,但并非所有系统都有这么理想的状态。
假如旧密码都是被散列加密过的,那么可以使用下列两种选择

  1. 使用增量更新的方法。当用户输入的密码正确时,判断数据库中的密码是否为BCrypt密文,如果不是,则尝试使用用户输入的密码重新生成BCrpyt密文并写回数据库。
  2. 以旧的加密方案作为基础接入BCrpyt加密,eg: 旧的方案是MD5加密,即数据库中的所有密码都是MD5形式的密码,那么直接把这些密码当作明文,先“跑库”生成BCrypt密文,再使用encode和matches两个方法在执行BCrypt加密之前都先用MD5运算一遍即可。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值