做者:Eugen Paraschivgit
轉載自公衆號:stackgcgithub
本文將討論註冊流程中的一個關鍵部分 —— 密碼編碼(以非明文方式存儲密碼)。算法
Spring Security 支持部分編碼機制 —— 本文將使用 BCrypt 編碼方式,它一般被認爲是密碼編碼的最佳解決方案。spring
大多數其餘機制,如 MD5PasswordEncoder 和 ShaPasswordEncoder 使用了較弱的編碼算法,如今已被棄用了。數據庫
咱們首先在配置中將 BCryptPasswordEncoder 定義爲一個 bean:ide
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
複製代碼
一些舊的實現方式,好比 SHAPasswordEncoder,會要求客戶端在編碼密碼時傳入一個 salt 值(又稱鹽值)。ui
然而 BCrypt 方式不一樣,它會在內部產生一個隨機鹽值。這很重要,由於這意味着每次調用都會有不一樣的結果,所以咱們只須要對密碼進行一次編碼。編碼
另外請注意,BCrypt 算法會生成一個長度爲 60 的字符串,所以咱們須要確保存儲密碼的列有足夠的空間。常見的一個錯誤是建立一個長度不足的列,而後在驗證時獲得一個無效的用戶名或密碼錯誤。spa
在用戶註冊流程中,咱們使用 UserService 中的 PasswordEncoder 對密碼進行散列處理:
示例 3.1 — UserService 對密碼散列處理
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
if (emailExist(accountDto.getEmail())) {
throw new EmailExistsException(
"There is an account with that email adress:" + accountDto.getEmail());
}
User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
user.setEmail(accountDto.getEmail());
user.setRole(new Role(Integer.valueOf(1), user));
return repository.save(user);
}
複製代碼
讓咱們來處理這個流程的另外一部分,在用戶認證時對密碼進行編碼。
首先,咱們須要將以前定義的密碼編碼器 bean 注入到身份驗證提供器中:
@Autowired
private UserDetailsService userDetailsService;
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
複製代碼
security 配置很簡單:
最後,咱們須要在 security XML 配置中引用這個認證提供器:
<authentication-manager>
<authentication-provider ref="authProvider" />
</authentication-manager>
複製代碼
或者,您也能夠使用 Java 配置:
@Configuration
@ComponentScan(basePackages = { "org.baeldung.security" })
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
...
}
複製代碼
本教程繼上一篇的註冊流程,經過利用簡單卻很是強大的 BCrypt 實現來對密碼進行編碼並存儲到數據庫中。
該註冊流程在 Spring Security 教程中已經徹底實現,您能夠在 GitHub 項目中找到。