使用spring security BCryptPasswordEncoder接入系统

 更新时间:2023年08月25日 10:31:58   作者:kaili230  
这篇文章主要介绍了使用spring security BCryptPasswordEncoder接入系统方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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运算一遍即可。

spring security的BCryptPasswordEncoder问题

早些年,那会把一个老项目的登录模块重构,从Shiro转Spring Security,那时候快速换完后没多看,最近又在公司做类似同样的操作,给一个老项目加上Spring Security。所以我决定简单写点什么。相信用过Spring Security的伙伴们,应该对这个BCryptPasswordEncoder 都有好奇。为啥好奇, 这个家伙的加密方法encode每次生成的密后密码都不一样,但是校验方法matches却能准确地去检验匹配。

不多说,现在一起来看看。

1. 先看encode这个方法

不用细看,我们看两个关键信息:

  • BCrypt.gensalt
  • BCrypt.hashpw

没错,这个加密算法其实是 强哈希+盐+密钥(默认用密码)。 因为使用到了哈希,所以是不可逆。

这也就能初步明白matches 为什么只能用来做校验匹配,而不是直接解密。 这点意味着就算你加密后的密码泄露了,别人想直接得到明文几乎是不可能的。

 接下来,有必要看hashpw么,放到下面一起看。

2. 接下来看matches这个方法

关注点:

BCrypt.checkpw(rawPassword.toString(), encodedPassword);

 

没错,因为哈希无法逆操作,所以匹配过程中也是用了hashpw 。 可以看到了checkpw这个方法,我们传入的密文其实命名已经是 hashed ,没错,这个密文就是一个带有盐值的哈希。

hashpw 里面,前面一大堆都是在校验密文格式对不对,因为可以看到我们的加密后得到的密文格式是不是有点像?

符合格式了就开始截取:

明文有了,盐值也有了,那么匹配就跟我们一般接口的sign认证一样了。 

简单的了解就到此吧。 

PS: 这个BCryptPasswordEncoder加密&校验方法当个工具类,导包+启动类屏蔽Security默认自动装配,用起来也是可以的。

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java操作gaussDB数据库的实现示例

    java操作gaussDB数据库的实现示例

    本文主要介绍了java操作gaussDB数据库的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Java锁机制Lock用法示例

    Java锁机制Lock用法示例

    这篇文章主要介绍了Java锁机制Lock用法,结合具体实例形式分析了Java锁机制的相关上锁、释放锁、隐式锁、显式锁等概念与使用技巧,需要的朋友可以参考下
    2018-08-08
  • java学习笔记之马踏棋盘算法

    java学习笔记之马踏棋盘算法

    这篇文章主要为大家详细介绍了java学习笔记之马踏棋盘算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java连接SqlServer错误的完美解决方法

    Java连接SqlServer错误的完美解决方法

    我们在做Java或者C#连接数据库的时候,常常遇到连接SqlServer失败的问题,明明检查了好几遍代码没问题了,还是连接不上,下面这篇文章主要给大家介绍了关于Java连接SqlServer错误的完美解决方法,需要的朋友可以参考下
    2023-04-04
  • Java中Date和LocalDate区别与介绍

    Java中Date和LocalDate区别与介绍

    本文主要介绍了Java中Date和LocalDate区别与介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • java中 spring 定时任务 实现代码

    java中 spring 定时任务 实现代码

    java中 spring 定时任务 实现代码,需要的朋友可以参考一下
    2013-03-03
  • spring中@ControllerAdvice 注解的使用

    spring中@ControllerAdvice 注解的使用

    @ControllerAdvice注解是Spring3.2中新增的注解,主要用于Controller的全局配置,本文就来介绍一下spring中@ControllerAdvice 注解的使用,感兴趣的可以了解一下
    2024-09-09
  • Spring如何使用注解的方式创建bean

    Spring如何使用注解的方式创建bean

    这篇文章主要介绍了Spring如何使用注解的方式创建bean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Tree组件实现支持50W数据方法剖析

    Tree组件实现支持50W数据方法剖析

    这篇文章主要为大家介绍了Tree组件实现支持50W数据的方法剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • idea中如何全局搜索class文件或者字符串

    idea中如何全局搜索class文件或者字符串

    这篇文章主要介绍了idea中如何实现全局搜索class文件或者字符串问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论