[譯] 學習 Spring Security(六):密碼編碼

Oopsguy發表於2018-01-15

www.baeldung.com/spring-secu…

作者:Eugen Paraschiv

譯者:oopsguy.com

1、概述

本文將討論註冊流程中的一個關鍵部分 — 密碼編碼(以非明文方式儲存密碼)。

Spring Security 支援一部分編碼機制 — 本文將使用 BCrypt 編碼方式,因為它通常被作為最佳的解決方案。

大多數其他機制,如 MD5PasswordEncoderShaPasswordEncoder 使用了較弱演算法的編碼方式,現在已被棄用了。

2、定義密碼編碼器

我們首先在配置中將 BCryptPasswordEncoder 定義為一個 bean:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}
複製程式碼

一些舊的實現方式,比如 SHAPasswordEncoder,會要求客戶端在編碼密碼時傳入一個 salt 值(又稱鹽值)。

然而 BCrypt 方式不同,它會在內部產生一個隨機鹽值。這很重要,因為這意味著每次呼叫都會有不同的結果,因此我們只需要對密碼進行一次編碼。

另外請注意,BCrypt 演算法會生成一個長度為 60 的字串,因此我們需要確儲存儲密碼的列有足夠的空間。一個常見的錯誤是建立一個長度不足的列,然後在驗證時得到一個無效的使用者名稱或密碼錯誤。

3、在註冊時編碼密碼

在使用者註冊流程中,我們使用 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);
}
複製程式碼

4、在認證時編碼密碼

現在讓我們來處理這個流程的另一半,在使用者認證時對密碼進行編碼。

首先,我們需要將之前定義的密碼編碼器 bean 注入到身份驗證提供器中:

@Autowired
private UserDetailsService userDetailsService;
 
@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}
複製程式碼

security 配置很簡單:

  • 注入 UserDetailsService 實現類
  • 定義一個認證提供器,引用了 UserDetailsService
  • 啟用了密碼編碼器

最後,我們需要在 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());
    }
     
    ...
}
複製程式碼

5、結論

本教程繼上一篇的註冊流程,通過利用簡單卻非常強大的 BCrypt 實現展示瞭如何正確地儲存密碼到資料庫中。

該註冊流程在 Spring Security 教程中已經完全實現,您可以在 GitHub 專案中找到 — 這是一個 Eclipse 專案,應該很容易匯入和執行。

原文專案程式碼

github.com/eugenp/spri…

相關文章