Я перехожу из Spring Boot 1.4.9 в Spring Boot 2.0, а также в Spring Security 5, и я пытаюсь выполнить аутентификацию через OAuth 2. Но я получаю эту ошибку:
java.lang.IllegalArgumentException: нет идентификатора PasswordEncoder для идентификатора "null
Из документации Spring Безопасность 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
С тем, что первая ошибка исчезла, и теперь, когда я пытаюсь сделать аутентификацию, я становлюсь ниже ошибки:
java.lang.IllegalArgumentException: нет идентификатора PasswordEncoder для идентификатора "null
Чтобы решить эту проблему, я попробовал все приведенные ниже вопросы из Stackoverflow:
Вот вопрос, похожий на мой, но не answerd:
ПРИМЕЧАНИЕ. Я уже храню зашифрованный пароль в базе данных, поэтому не нужно снова закодировать в UserDetailsService
.
В документации Spring Security 5 они предложили обработать это исключение, используя:
DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)
Если это исправление, то где я должен его поместить? Я попытался поместить его в PasswordEncoder
bean, как показано ниже, но он не работал:
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);
}
}
Пожалуйста, помогите мне с этой проблемой. У меня есть часы, чтобы исправить это, но не удалось исправить.