在之前的文章中密碼都是使用明文的方式進行存儲,但這樣會有很大的安全隱患。所以正常做系統時,密碼都要加密處理。而在 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);
}
}