Spring Security 5:Pro id „null“ není namapován žádný PasswordEncoder
Provádím migraci z Spring Boot 1.4.9 na Spring Boot 2.0 a také na Spring Security 5 a pokouším se provést ověření přes OAuth 2. Zobrazuje se mi však tato chyba:
java.lang.IllegalArgumentException:Pro id „null
není namapován žádný PasswordEncoderZ dokumentace Spring Security 5 se dozvídám, že formát úložiště pro heslo se změnil.
Ve svém aktuálním kódu jsem vytvořil svůj kodér hesla jako:
@Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
Vypisovalo mi to však níže uvedenou chybu:
Zakódované heslo nevypadá jako BCrypt
Aktualizuji tedy kodér podle dokumentu Spring Security 5 na:
@Bean public PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }
Pokud nyní vidím heslo v databázi, ukládá se jako
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ
S touto 1. chybou pryč a nyní, když se pokouším provést ověření, dostávám níže uvedenou chybu:
java.lang.IllegalArgumentException:Pro id „null
není namapován žádný PasswordEncoderK vyřešení tohoto problému jsem vyzkoušel všechny níže uvedené otázky od Stackoverflow:
-
Spring Boot PasswordEncoder Error
-
Spring Oauth2. V DaoAuthenticationProvider
není nastaven kodér hesla
Zde je otázka podobná té mé, ale nezodpovězená:
- Spring Security 5 – Migrace hesel
POZNÁMKA:V databázi již ukládám zašifrované heslo, takže není třeba znovu kódovat v UserDetailsService
.
V dokumentaci Spring security 5 navrhli, abyste tuto výjimku zvládli pomocí:
DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)
Pokud je toto oprava, kam ji mám umístit? Zkusil jsem to dát do PasswordEncoder
fazole jako níže, ale nefungovala:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders); def.setDefaultPasswordEncoderForMatches(passwordEncoder);
Třída 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(); } }
Konfigurace 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); } }
Prosím, poraďte mi s tímto problémem. Strávil jsem hodiny, abych to napravil, ale nejsem schopen to opravit.
Odpověď
Když konfigurujete ClientDetailsServiceConfigurer
, musíte také použít nový formát uložení hesla na tajný klíč klienta.
.secret("{noop}secret")