一尘不染

Spring Security 5:没有为id“ null”映射的PasswordEncoder

spring

我正在从Spring Boot 1.4.9迁移到Spring Boot 2.0,还迁移到Spring Security 5,并且正在尝试通过OAuth 2进行身份验证。但是我收到此错误:

java.lang.IllegalArgumentException:没有为id“ null映射的PasswordEncoder

从Spring Security 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:没有为id“ null映射的PasswordEncoder

注意:我已经在数据库中存储了加密的密码,因此无需在中再次编码UserDetailsService

在Spring Security 5文档中,他们建议你可以使用以下方法处理此异常:

DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)

如果这是解决方法,那我应该放在哪里?我试图将其放入PasswordEncoder如下所示的bean中,但是没有用:

DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders);
def.setDefaultPasswordEncoderForMatches(passwordEncoder);

MyWebSecurityclass

@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);
    }
}

请引导我解决这个问题。我已经花了几个小时来解决此问题,但无法解决。


阅读 467

收藏
2020-04-13

共1个答案

一尘不染

在配置时ClientDetailsServiceConfigurer,还必须将新的密码存储格式应用于客户端密钥。

.secret("{noop}secret")
2020-04-13