在之前的文章中密码都是使用明文的方式进行存储,但这样会有很大的安全隐患。所以正常做系统时,密码都要加密处理。而在 Spring Boot 中配置密码加密非常容易,下面通过样例进行演示。
九、密码加密配置
1、样例代码
(1)要配置密码加密只需要修改两个地方。首先要修改 HttpSecurity 配置中的 PasswordEncoder 这个Bean 的实现,这里我们采用 BCryptPasswordEncoder 加密方案。
Spring Security 提供了多种密码加密方案,官方推荐使用 BCryptPasswordEncoder:
- BCryptPasswordEncoder 使用 BCrypt 强哈希函数,开发者在使用时可以选择提供 strength 和 SecureRandom 实例。
- strength 取值在 4~31 之间(默认为 10)。strength 越大,密钥的迭代次数越多(密钥迭代次数为 2^strength)
(2)接着将用户的密码改成使用 BCryptPasswordEncoder 加密后的密码(如果是数据库认证,库里的密码同样也存放加密后的密码)
注意:虽然这里三个用户加密后的密码不一样,但明文其实都是 123。这是因为即使同一密码每次 Bcrypt 生成的结果都会变化
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
// 指定密码的加密方式
@Bean
PasswordEncoder passwordEncoder(){
// 使用BCrypt强哈希函数加密方案,密钥迭代次数设为10(默认即为10)
return new BCryptPasswordEncoder(10);
}
// 配置用户及其对应的角色
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root")
.password("$2a$10$OahHKAjiYRxJb9eBeDNeTe0HapawUSY5qYRl/6O2qJUyK58ontFwW")
.roles("DBA")
.and()
.withUser("admin")
.password("$2a$10$nwG.X7cRIkRUN0siaaXI6uDnbZuB1XCnQK7KQ1sRWat69fIKF8ste")
.roles("ADMIN")
.and()
.withUser("hangge")
.password("$2a$10$AkEWXIFbKRDlypQ.kQxNDu.85ZCuiv77CGJLikwLxURDrVav6IDpy")
.roles("USER");
}
// 配置 URL 访问权限
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 开启 HttpSecurity 配置
.antMatchers("/db/**").hasRole("DBA") // db/** 模式URL需DBA角色
.antMatchers("/admin/**").hasRole("ADMIN") // admin/** 模式URL需ADMIN角色
.antMatchers("/user/**").hasRole("USER") // user/** 模式URL需USER角色
.anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问)
.and().formLogin().loginProcessingUrl("/login").permitAll() // 开启表单登录并配置登录接口
.and().csrf().disable(); // 关闭csrf
}
}
2、运行测试
启动项目后,我们仍然使用 123 这个密码进行登录。
附:生成 Bcrypt 密码
通常来说用户信息是存储在数据库中,因此需要在用户注册时对密码进行加密处理。下面代码作用是当用户将密码从前端传过来之后,通过调用 BCryptPasswordEncoder 实例中的 encode 方法对密码进行加密处理,加密完成后将密文存入数据库。
@Service
public class RegService {
public int reg(String username, String password) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
String encodePasswod = encoder.encode(password);
return saveToDb(username, encodePasswod);
}
}