最佳答案
我正在从 SpringBoot1.4.9迁移到 SpringBoot2.0,也迁移到 SpringSecurity5,我正在尝试通过 OAuth2进行身份验证。但我得到了这个错误:
IllegalArgumentException: 没有为 id“ null”映射的 PasswordEncoder
从 春季安全5的文档中,我得知 更改密码的存储格式。
在我当前的代码中,我已经创建了我的密码编码器 bean:
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
然而,它给了我以下错误:
编码密码看起来不像 BCrypt
因此,我根据 春季安全5文档将编码器更新为:
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
现在,如果我可以看到数据库中的密码,它存储为
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ
随着第一个错误的消失,现在当我尝试进行身份验证时,我得到了以下错误:
IllegalArgumentException: 没有为 id“ null”映射的 PasswordEncoder
为了解决这个问题,我尝试了 Stackoverflow 提出的以下所有问题:
这里有一个类似于我的问题,但没有答案:
注意: 我已经在数据库中存储了加密的密码,所以不需要在 UserDetailsService
中再次编码。
在 春季安全5文档中,他们建议您可以使用以下方法处理这个异常:
SetDefaultPasswordEncoderForMatches (PasswordEncoder)
如果这是修复,那么我应该把它放在哪里?我已经尝试把它放在 PasswordEncoder
豆像下面这样,但它没有工作:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders);
def.setDefaultPasswordEncoderForMatches(passwordEncoder);
MyWebSecurity 类
@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);
}
}
请指导我这个问题。我已经花了几个小时来解决这个问题,但无法修复。