在上一个Demo的基础之上,在 WebSecurityConfig
增加如下代码:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
//配置 UserDetailsService 实现类,实现自定义登录校验
.userDetailsService(dbUserDetailService)
//配置密码加密规则
.passwordEncoder(passwordEncoder());
}
/**
* 密码加密,必须为 @Bean ,否则报错
* 作用:实例化密码加密规则,该规则首先会校验数据库中存储的密码是否符合其规则(经过 BCryptPasswordEncoder 加密的密码
* 的字符串符合一定的规则):
* 1.若不符合,直接报错;
* 2.若符合,则会将前端传递的密码经过 BCryptPasswordEncoder 加密,再和数据库中的密码进行比对,一样则通过
* 所以,这里要求,我们存入进数据库的密码不能是明文,而必须是经过 BCryptPasswordEncoder 加密后,才能存入数据库
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
BCryptPasswordEncoder相关知识:
用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。
特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。
BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。
BCryptPasswordEncoder 是在哪里使用的?
登录时用到了 DaoAuthenticationProvider
,它有一个方法
#additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
,此方法用来校验从数据库取得的用户信息和用户输入的信息是否匹配。
在注册时,需要对用户密码加密
应用 BCryptPasswordEncoder 之后,明文密码是无法被识别的,就会校验失败,只有存入密文密码才能被正常识别。所以,应该在注册时对用户密码进行加密。
private String encryptPassword(String password) {
// BCryptPasswordEncoder 加密
return new BCryptPasswordEncoder().encode(password);
}
新用户注册后,数据库中就会存入密文密码,示例:
补充说明:即使不同的用户注册时输入相同的密码,存入数据库的密文密码也会不同。