我正在从Spring Boot 1.4.9迁移到Spring Boot 2.0,还迁移到Spring Security 5,并且正在尝试通过OAuth 2进行身份验证。但是我收到此错误:
java.lang.IllegalArgumentException:没有为id“ null映射的PasswordEncoder
从Spring Security 5的文档中,我知道密码的存储格式已更改。
在当前代码中,我将密码编码器bean创建为:
@Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
但是它给了我下面的错误:
编码密码看起来不像BCrypt
因此,我根据Spring Security 5文档将编码器更新为:
@Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }
现在,如果我可以在数据库中看到密码,密码将存储为
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ 随着第一个错误消失,现在当我尝试进行身份验证时,我得到以下错误:
注意:我已经在数据库中存储了加密的密码,因此无需在中再次编码UserDetailsService。
UserDetailsService
在Spring Security 5文档中,他们建议你可以使用以下方法处理此异常:
DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)
如果这是解决方法,那我应该放在哪里?我试图将其放入PasswordEncoder如下所示的bean中,但是没有用:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders); def.setDefaultPasswordEncoderForMatches(passwordEncoder);
MyWebSecurityclass
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers(HttpMethod.OPTIONS) .antMatchers("/api/user/add"); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } }
MyOauth2配置
@Configuration @EnableAuthorizationServer protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Bean public TokenStore tokenStore() { return new InMemoryTokenStore(); } @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Bean public TokenEnhancer tokenEnhancer() { return new CustomTokenEnhancer(); } @Bean public DefaultAccessTokenConverter accessTokenConverter() { return new DefaultAccessTokenConverter(); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore()) .tokenEnhancer(tokenEnhancer()) .accessTokenConverter(accessTokenConverter()) .authenticationManager(authenticationManager); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .inMemory() .withClient("test") .scopes("read", "write") .authorities(Roles.ADMIN.name(), Roles.USER.name()) .authorizedGrantTypes("password", "refresh_token") .secret("secret") .accessTokenValiditySeconds(1800); } }
请引导我解决这个问题。我已经花了几个小时来解决此问题,但无法解决。
在配置时ClientDetailsServiceConfigurer,还必须将新的密码存储格式应用于客户端密钥。
ClientDetailsServiceConfigurer
.secret("{noop}secret")