Spring Security灵活的PasswordEncoder加密方式
本章基于Spring Security 5.4.1版本编写,从5.x版本开始引入了很多新的特性。
为了适配老系统的安全框架升级,Spring Security也是费劲了心思,支持不同的密码加密方式,而且根据不同的用户可以使用不同的加密方式。
构建Spring Security项目
Spring Security的集成使用还是很简单的,根据项目使用的框架不同大致分为两种集成方式:
SpringBoot方式集成SecurityBom方式集成
SpringBoot方式构建
在pom.xml文件内添加如下内容:
1 | <dependency> |
SecurityBom方式构建
spring-security-bom是一个提供了Spring Security指定版本的全部默认依赖的pom类型项目,我们可以通过dependencyManagement进行配置到项目中,这样我们就可以直接添加对应的dependency了(注意:版本号因为bom已经注定,所以dependency不需要指定.)。
在pom.xml文件内添加如下内容:
1 | <dependencies> |
注意事项:我们构建Web类型的安全项目时,
spring-security-config、spring-security-core、spring-security-web三个依赖都是必须添加的。
PasswordEncoder
PasswordEncoder是Spring Security提供的密码加密方式的接口定义,源码类如下所示:
1 | public interface PasswordEncoder { |
#encode
该方法提供了明文密码的加密处理,加密后密文的格式主要取决于
PasswordEncoder接口实现类实例。#matches
匹配存储的密码以及登录时传递的密码(
登录密码是经过加密处理后的字符串)是否匹配,如果匹配该方法则会返回true.
内置的PasswordEncoder实现列表
NoOpPasswordEncoder(已废除)
明文密码加密方式,该方式已被废除(不建议在生产环境使用),不过还是支持开发阶段测试
Spring Security的时候使用。
DelegatingPasswordEncoder
在之前版本集成Spring Secuirty时,我们需要通过@Bean的方式来配置全局统一使用的密码加密方式(PasswordEncoder),当然这种方式现在还是适用的,不过在5.x版本开始为了支持动态的多种密码加密方式,DelegatingPasswordEncoder委托加密方式类应用而生,它内部其实是一个Map集合,根据传递的Key(Key为加密方式)获取Map集合的Value,而Value则是具体的PasswordEncoder实现类。
DelegatingPasswordEncoder建立密码格式的规则,格式如:{bcrypt}encodePassword,示例如下所示:
1 | // {bcrypt}格式会委托给BCryptPasswordEncoder加密类 |
指定用户使用PasswordEncoder
DelegatingPasswordEncoder是默认的PasswordEncoder加密方式,所以我们可以为不同的用户配置所使用不同的密码加密方式,只需要密码格式按照:{away}encodePassword来进行持久化即可。
1 |
|
上面是使用内存方式存储安全用户的实现代码,在创建UserDetailsService类的实例时将用户列表通过构造参数进行传递。
所创建的用户:admin,采用MD5的加密方式进行密码编码,这里需要注意的是MD5加密后的字符串必须为小写32位。
所创建的用户:hengboy,采用bcrypt方式进行密码编码。
所创建的用户:yuqiyu,采用pbkdf2方式进行密码编码。
覆盖默认的PasswordEncoder
Spring Security 5.x版本默认的PasswordEncoder方式改成了DelegatingPasswordEncoder委托类,不过如果是通过PasswordEncoderFactories#createDelegatingPasswordEncoder方法创建的DelegatingPasswordEncoder实例时,默认其实使用的还是BCryptPasswordEncoder,源码如下所示:
1 | public static PasswordEncoder createDelegatingPasswordEncoder() { |
如果我们项目中不需要使用DelegatingPasswordEncoder委托密码编码方式,可以通过@Bean的方式来统一配置全局共用的PasswordEncoder,如下所示:
1 |
|
可以根据项目自行选择所使用的
PasswordEncoder实现类。
Spring Security灵活的PasswordEncoder加密方式
https://blog.minbox.org/spring-security-flexible-password-encoder.html

OAuth vs SAML vs OpenID
