Spring Security 5:没有为 id“null"映射的 PasswordEncoder [英] Spring Security 5 : There is no PasswordEncoder mapped for the id "null"

查看:33
本文介绍了Spring Security 5:没有为 id“null"映射的 PasswordEncoder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

java.lang.IllegalArgumentException:没有为 idnull"映射的 PasswordEncoder

来自Spring Security 5,我知道了更改密码的存储格式.

在我当前的代码中,我将密码编码器 bean 创建为:

@Bean公共 BCryptPasswordEncoder passwordEncoder() {返回新的 BCryptPasswordEncoder();}

但是它给了我以下错误:

<块引用>

编码后的密码看起来不像 BCrypt

所以我按照 Spring Security 5 文档到:

@Bean公共密码编码器密码编码器(){返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}

现在,如果我可以在数据库中看到密码,它将存储为

{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ

第一个错误消失了,现在当我尝试进行身份验证时,出现以下错误:

<块引用>

java.lang.IllegalArgumentException: 没有为 idnull"映射的 PasswordEncoder

为了解决这个问题,我尝试了以下来自 Stackoverflow 的所有问题:

这里有一个与我相似但没有回答的问题:

注意:我已经将加密密码存储在数据库中,因此无需在 UserDetailsS​​ervice 中再次编码.

他们建议您可以使用以下方法处理此异常的 Spring security 5 文档:

<块引用>

DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)

如果这是修复,那么我应该把它放在哪里?我试图把它放在 PasswordEncoder bean 中,如下所示,但它不起作用:

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

MyWebSecurity 类

@Configuration@启用网络安全公共类 SecurityConfiguration 扩展了 WebSecurityConfigurerAdapter {@自动连线私有 UserDetailsS​​ervice userDetailsS​​ervice;@豆角,扁豆公共密码编码器密码编码器(){返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}@自动连线public void configureGlobal(AuthenticationManagerBuilder auth) 抛出异常 {auth.userDetailsS​​ervice(userDetailsS​​ervice).passwordEncoder(passwordEncoder());}@覆盖公共无效配置(WebSecurity web)抛出异常{网络.忽略().antMatchers(HttpMethod.OPTIONS).antMatchers("/api/user/add");}@覆盖@豆角,扁豆公共 AuthenticationManager authenticationManagerBean() 抛出异常 {返回 super.authenticationManagerBean();}}

MyOauth2 配置

@Configuration@EnableAuthorizationServer受保护的静态类 AuthorizationServerConfiguration 扩展了 AuthorizationServerConfigurerAdapter {@豆角,扁豆公共令牌商店令牌商店(){返回新的 InMemoryTokenStore();}@自动连线@Qualifier("authenticationManagerBean")私有 AuthenticationManager authenticationManager;@豆角,扁豆公共 TokenEnhancer tokenEnhancer() {返回新的 CustomTokenEnhancer();}@豆角,扁豆公共 DefaultAccessTokenConverter accessTokenConverter() {返回新的 DefaultAccessTokenConverter();}@覆盖公共无效配置(AuthorizationServerEndpointsConfigurer 端点)抛出异常{端点.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancer()).accessTokenConverter(accessTokenConverter()).authenticationManager(authenticationManager);}@覆盖公共无效配置(ClientDetailsS​​erviceConfigurer 客户端)抛出异常 {客户.在记忆中().withClient("测试").scopes("读", "写").authorities(Roles.ADMIN.name(), Roles.USER.name()).authorizedGrantTypes("密码", "refresh_token").secret("秘密").accessTokenValiditySeconds(1800);}}

请指导我解决这个问题.我花了几个小时来解决这个问题,但无法解决.

解决方案

在配置 ClientDetailsS​​erviceConfigurer 时,还必须应用新的 密码存储格式到客户端密钥.

.secret("{noop}secret")

I am migrating from Spring Boot 1.4.9 to Spring Boot 2.0 and also to Spring Security 5 and I am trying to do authenticate via OAuth 2. But I am getting this error:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null

From the documentation of Spring Security 5, I get to know that storage format for password is changed.

In my current code I have created my password encoder bean as:

@Bean
public BCryptPasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

However it was giving me below error:

Encoded password does not look like BCrypt

So I update the encoder as per the Spring Security 5 document to:

@Bean
public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

Now if I can see password in database it is storing as

{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ

With that 1st error gone and now when I am trying to do authentication I am getting below error:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null

To solve this issue I tried all the below questions from Stackoverflow:

Here is a question similar to mine but not answerd:

NOTE: I am already storing encrypted password in database so no need to encode again in UserDetailsService.

In the Spring security 5 documentation they suggested you can handle this exception using:

DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(PasswordEncoder)

If this is the fix then where should I put it? I have tried to put it in PasswordEncoder bean like below but it wasn't working:

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

MyWebSecurity class

@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

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

Please guide me with this issue. I have spend hours to fix this but not able to fix.

解决方案

When you are configuring the ClientDetailsServiceConfigurer, you have to also apply the new password storage format to the client secret.

.secret("{noop}secret")

这篇关于Spring Security 5:没有为 id“null"映射的 PasswordEncoder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆