Java >> Java tutoriál >  >> Tag >> Spring

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ý PasswordEncoder

Z 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ý PasswordEncoder

K 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")

Java Tag