在之前集成 spring-security-oauth2 搭建 OAuth2.0 服务时,依赖项 Spring Security 5 默认引入了更安全的加/解密机制,如果之前程序使用纯文本的方式存储密码或低版本升级到 Spring Security 5 后可能会出现如下错误。
Encoded password does not look like BCrypt java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233) at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)
Spring Security 5 对 PasswordEncoder 做了相关的重构,原先默认配置的 PlainTextPasswordEncoder 明文密码被移除了(本身明文存储密码也是不合适的一种方式,只适用与测试环境)。
@Bean public static NoOpPasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); }
可以通过使用 PasswordEncoderFactories 类创建一个 DelegatingPasswordEncoder 的方式来解决这个问题。
Reverting to
NoOpPasswordEncoder
is not considered to be secure. You should instead migrate to usingDelegatingPasswordEncoder
to support secure password encoding.https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#troubleshooting
@Bean public BCryptPasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } /** * 配置授权的用户信息 * @param authenticationManagerBuilder * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { // PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); // authenticationManagerBuilder.inMemoryAuthentication() // .withUser("irving") // .password(encoder.encode("123456")) // .roles("read"); authenticationManagerBuilder.userDetailsService(userDetailService).passwordEncoder(passwordEncoder()); }