1.概述
在Spring Security 4中,可以使用記憶體中身份驗證以純文字格式儲存密碼。
對版本5中的密碼管理過程進行了重大改進,為密碼編碼和解碼引入了更安全的預設機制。這意味著如果您的Spring應用程式以純文字格式儲存密碼,升級到Spring Security 5可能會導致問題。
在這個簡短的教程中,我們將描述其中一個潛在的問題,並展示該問題的解決方案。
2. Spring Security 4
我們首先展示一個標準的安全配置,它提供簡單的記憶體中身份驗證(適用於Spring 4):
@Configuration
public class InMemoryAuthWebSecurityConfigurer
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("spring")
.password("secret")
.roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/private/**")
.authenticated()
.antMatchers("/public/**")
.permitAll()
.and()
.httpBasic();
}
}
此配置定義所有/私有/對映方法的身份驗證以及/ public /下所有內容的公共訪問。
如果我們在Spring Security 5下使用相同的配置,我們會收到以下錯誤:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
該錯誤告訴我們由於沒有為我們的記憶體中身份驗證配置密碼編碼器,因此無法解碼給定的密碼。
3. Spring Security 5
我們可以通過使用PasswordEncoderFactories類定義DelegatingPasswordEncoder來解決此錯誤。
我們使用此編碼器通過AuthenticationManagerBuilder配置我們的使用者:
@Configuration
public class InMemoryAuthWebSecurityConfigurer
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("spring")
.password(encoder.encode("secret"))
.roles("USER");
}
}
現在,通過這種配置,我們使用BCrypt以以下格式儲存我們的記憶體中密碼:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
雖然我們可以定義自己的一組密碼編碼器,但建議堅持使用PasswordEncoderFactories中提供的預設編碼器。
3.1.遷移現有密碼
我們可以通過以下方式將現有密碼更新為推薦的Spring Security 5標準:
更新純文字儲存密碼及其編碼值:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);
字首雜湊儲存的密碼及其已知的編碼器識別符號:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
當儲存密碼的編碼機制未知時,請求使用者更新其密碼
4.結論
在這個快速示例中,我們使用新的密碼儲存機制將有效的Spring 4記憶體中認證配置更新到Spring 5。
與往常一樣,您可以在GitHub專案中找到源代碼。