没有为 id“null"映射的 PasswordEncoder在春季安全 [英] There is no PasswordEncoder mapped for the id "null" in Spring Security

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

问题描述

我正在从 Spring Boot 1.5.12 迁移到 Spring Boot 2.0 以及 Spring Security 5,并且我正在尝试通过 OAuth 2 进行身份验证.但即使在使用委托 {noop} 后我仍然收到此错误:

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

这是我的代码:

安全配置

public class SecurityConfig extends WebSecurityConfigurerAdapter {@自动连线private CustomUserDetailsS​​ervice userDetailsS​​ervice;@豆public PasswordEncoder passwordEncoder() {返回 PasswordEncoderFactories.createDelegatingPasswordEncoder();}公共安全配置(){超级();SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);}@覆盖protected void configure(final HttpSecurity http) 抛出异常 {http.cors().and().csrf().disable().exceptionHandling().and().authorizeRequests().antMatchers("/api/v1/**").authenticated().and().httpBasic();}@覆盖public void configure(final WebSecurity web) 抛出异常 {web.ignoring().antMatchers(/v2/api-docs"、/configuration/ui"、/swagger-resources"、/configuration/security"、/webjars/**"、/swagger-resources/configuration/ui",/swagger-resources/configuration/security",/swagger-ui.html"、/admin11/*"、/*.html"、/*.jsp"、/favicon.ico"、//*.html";, "//*.css", "//*.js","/admin11/monitoring","/proxy.jsp");}@覆盖protected void configure(final AuthenticationManagerBuilder auth) 抛出异常 {auth.userDetailsS​​ervice(userDetailsS​​ervice).passwordEncoder(passwordEncoder());}@豆@覆盖公共 AuthenticationManager authenticationManagerBean() 抛出异常 {返回 super.authenticationManagerBean();}}

Oauth2AuthorizationServerConfig

public class Oauth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@自动连线@Qualifier(authenticationManagerBean")私有 AuthenticationManager authenticationManager;@自动连线private CustomUserDetailsS​​ervice userDetailsS​​ervice;@自动连线私有 JdbcTokenStore jdbcTokenStore;@豆公共令牌商店令牌商店(){返回 jdbcTokenStore;}@豆公共 JwtAccessTokenConverter accessTokenConverter() {CustomTokenEnhancer 转换器 = new CustomTokenEnhancer();Converter.setSigningKey(secret_api");返回转换器;}@覆盖公共无效配置(最终 AuthorizationServerEndpointsConfigurer 端点)抛出异常 {endpoints.tokenStore(tokenStore()).accessTokenConverter(accessTokenConverter()).authenticationManager(authenticationManager).userDetailsS​​ervice(userDetailsS​​ervice).pathMapping("/oauth/token", "/api/v1/oauth/token");}@覆盖公共无效配置(ClientDetailsS​​erviceConfigurer 客户端)抛出异常 {clients.inMemory().withClient("app").secret("{noop}secret").authorizedGrantTypes("password", "authorization_code").scopes("read", "write").autoApprove(true).accessTokenValiditySeconds(0);}@覆盖public void configure(final AuthorizationServerSecurityConfigurer oauthServer) 抛出异常 {oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}@豆公共 DefaultTokenServices defaultTokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();defaultTokenServices.setTokenStore(tokenStore());返回 defaultTokenServices;}}

自定义用户详细信息服务

公共接口 CustomUserDetailsS​​ervice 扩展 UserDetailsS​​ervice {UserDetails getByMsisdn(String msisdn);void initDummyUsers();}

为了解决这个问题,我尝试了 Stackoverflow 中的以下问题:

Spring Boot PasswordEncoder 错误

解决方案

Spring Security 文档正在解决您的确切问题.

<块引用>

存储的密码之一出现以下错误没有密码存储格式中描述的 ID.

java.lang.IllegalArgumentException: 没有映射的 PasswordEncoder对于 id null"在 org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233)在 org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)

<块引用>

解决错误的最简单方法是显式切换到提供密码编码的 PasswordEncoder.该解决它的最简单方法是弄清楚您的密码如何当前正在存储并明确提供正确的密码编码器.

如果您从 Spring Security 4.2.x 迁移,您可以恢复到通过暴露 NoOpPasswordEncoder bean 以前的行为.

所以你应该能够通过显式提供 PasswordEncoder

来解决这个问题

//记住,这是不好的做法@豆public PasswordEncoder passwordEncoder() {返回 NoOpPasswordEncoder.getInstance();}

或者更好地提供一个 自定义密码编码器委托人:

String idForEncode = "bcrypt";映射编码器 = new HashMap<>();encodings.put(idForEncode, new BCryptPasswordEncoder());encodings.put(noop", NoOpPasswordEncoder.getInstance());encodings.put(pbkdf2", new Pbkdf2PasswordEncoder());encodings.put(scrypt", new SCryptPasswordEncoder());encodings.put(sha256", new StandardPasswordEncoder());PasswordEncoder passwordEncoder =新的委托密码编码器(idForEncode,编码器);

全部取自 关于密码编码的官方春季安全文档.

I am migrating from Spring Boot 1.5.12 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 even after using delegate {noop}:

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

Here is my code :

SecurityConfig

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    
    @Autowired
    private CustomUserDetailsService userDetailsService;
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    public SecurityConfig() {
        super();
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
            http.cors().and().csrf().disable().exceptionHandling().and().authorizeRequests()
                .antMatchers("/api/v1/**")
                .authenticated().and().httpBasic();
    }

    @Override
    public void configure(final WebSecurity web) throws Exception {
            web.ignoring().antMatchers(
                "/v2/api-docs","/configuration/ui","/swagger-resources", "/configuration/security", "/webjars/**",
                "/swagger-resources/configuration/ui","/swagger-resources/configuration/security",
                "/swagger-ui.html", "/admin11/*", "/*.html", "/*.jsp", "/favicon.ico", "//*.html", "//*.css", "//*.js",
                "/admin11/monitoring","/proxy.jsp");
    }

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

Oauth2AuthorizationServerConfig

public class Oauth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private CustomUserDetailsService userDetailsService;
    
    @Autowired
    private JdbcTokenStore jdbcTokenStore;
    
    @Bean
    public TokenStore tokenStore() {
        return jdbcTokenStore;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        CustomTokenEnhancer converter = new CustomTokenEnhancer();
        converter.setSigningKey("secret_api");
        return converter;
    }

    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                
        endpoints.tokenStore(tokenStore())
                .accessTokenConverter(accessTokenConverter())
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                .pathMapping("/oauth/token", "/api/v1/oauth/token");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient("app").secret("{noop}secret")
                .authorizedGrantTypes("password", "authorization_code").scopes("read", "write")
                .autoApprove(true).accessTokenValiditySeconds(0);
    }

    @Override
    public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }
    
    @Bean
    public DefaultTokenServices defaultTokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }
}

CustomUserDetailsService

public interface CustomUserDetailsService extends UserDetailsService {

    UserDetails getByMsisdn(String msisdn);

    void initDummyUsers();
}

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

Spring Boot PasswordEncoder Error

解决方案

The Spring Security documentation is addressing your exact problem.

The following error occurs when one of the passwords that are stored has no id as described in Password Storage Format.

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped
for the id "null"
     at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233)
     at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)

The easiest way to resolve the error is to switch to explicitly provide the PasswordEncoder that you passwords are encoded with. The easiest way to resolve it is to figure out how your passwords are currently being stored and explicitly provide the correct PasswordEncoder.

If you are migrating from Spring Security 4.2.x you can revert to the previous behavior by exposing a NoOpPasswordEncoder bean.

So you should be able to fix this by explicitly providing the PasswordEncoder

// remember, its bad practice
@Bean
public PasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
}

Or even better supply a custom defined password encoder delegator:

String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());

PasswordEncoder passwordEncoder =
    new DelegatingPasswordEncoder(idForEncode, encoders);

All taken from the official spring security docs on password encoding.

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

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