Я перехожу с 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:
Вот вопрос, похожий на мой, но без ответа:
ПРИМЕЧАНИЕ. Я уже храню зашифрованный пароль в базе данных, поэтому нет необходимости повторно кодировать в UserDetailsService
.
В Spring security 5 они предложили обработать это исключение, используя:
DelegatingPasswordEncoder.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);
}
}
Пожалуйста, помогите мне решить эту проблему. У меня есть часы, чтобы исправить это, но я не могу исправить.
passwordEncoder
наClientDetailsServiceConfigurer
, либо префикс секрета с помощью {noop}. Надеюсь, что это имеет смысл и кому-то поможет. - person KellyM   schedule 06.04.2018mvn clean package
. Должно быть какая-то проблема с кешированием. - person Janac Meena   schedule 26.02.2021