明文保存密码是不可取的,可以使用 SHA
,BCrypt
等对密码进行加密。
BCrypt 算法与 MD5/SHA 算法有一个很大的区别,每次生成的 hash 值都是不同的,就可以免除存储 salt,暴力破解起来也更困难。BCrypt 加密后的字符长度比较长,有60位,所以用户表中密码字段的长度,如果打算采用 BCrypt 加密存储,字段长度不得低于 68(需要前缀 {bcrypt}
)。
下面的代码展示怎么使用 BCrypt 进行加密:
1 | import org.junit.Test; |
输出:
1 | $2a$10$l7vPVeqwb9GiVjURV5J2QO1CM5qxwk00/Ra5qEog0WgP7O5XV0Ble |
随意取其中任意一个都可以,因为每次生成都是不一样的,所以取第一个就可以了。
Spring Security 使用 BCrypt 加密
Spring Security 4 的时候需要配置 <password-encoder hash="bcrypt"/>
指定加密方式,Spring Security 5 不需要配置了,而是用户密码加前缀的方式表明加密方式,例如
{bcrypt}$2a$10$gQKUOoFuevnCkoej3.AvAO9YzHKCKYmKuiSfEGHL22piY2FfNDQYu
说明是使用 BCrypt 进行加密的{noop}Passw0rd
则是使用明文保存的密码 (noop: No Operation)
这样的好处是同一个系统可以使用多种加密方式,迁移用户到新系统时比较就省事了。Spring Security 5 默认支持的密码加密方式在 PasswordEncoderFactories 中定义:
1 | public static PasswordEncoder createDelegatingPasswordEncoder() { |
UserService
从数据源取得的密码是加密后的密码
1 | public class UserService { |
测试
- 访问 http://localhost:8080/admin
- 输入错误的用户名或密码,观察登陆失败的页面
- 输入正确的用户名和密码,继续登陆