Spring Security 5 报错There is no PasswordEncoder mapped for the id "null"根本解决

错误解释

请点击查看=> 问题和解决的官方文档 (本文主要是翻译和部分解释)

In Spring Security 4, it was possible to store passwords in plain text using in-memory authentication.
A major overhaul of the password management process in version 5 has introduced more secure default mechanism for encoding and decoding passwords. This means that if your Spring application stores passwords in plain text, upgrading to Spring Security 5 may cause problems.
In this short tutorial, we’ll describe one of those potential problems and demonstrate a solution to the issue.

即对于Spring Security 4, 支持使用明文密码(比如内存中的账号密码)。但是在Spring Security 5后都必须是用加密的密文。不然报错。


以下是Spring Security 4的在内存中添加账号密码的使用方式(明文)
@Configuration
public class InMemoryAuthWebSecurityConfigurer 
  extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        auth.inMemoryAuthentication()
          .withUser("spring")
          .password("secret")
          .roles("USER");
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/private/**")
          .authenticated()
          .antMatchers("/public/**")
          .permitAll()
          .and()
          .httpBasic();
    }
}

如果在 Spring Security 5还是这样写。必然报错如下

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

官方解释:没有为内存身份认证配置加密方法。因为Spring Security 5对安全规范更严格了。


解决方案

直接上代码
@Configuration
public class InMemoryAuthWebSecurityConfigurer 
  extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        // 配置加密功能对象
        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        auth.inMemoryAuthentication()
          .withUser("spring")
           // 调用对象给密码加密
          .password(encoder.encode("secret"))
          .roles("USER");
    }
}

密文shadow格式类似:
{bcrypt}$2a 10 10 MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS

也可以new 该对象:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword);


推荐

Although we can define our own set of password encoders, it’s recommended to stick with the default encoders provided in PasswordEncoderFactories.

推荐使用这个由PasswordEncoderFactories默认提供的加密编码器,即便可以自定义使用其他的。


注意

// 1
PasswordEncoder encoder1 = PasswordEncoderFactories.createDelegatingPasswordEncoder();

// 2 
PasswordEncoder encoder2 = new BCryptPasswordEncoder(); 

// s1 和 s2 长度格式都不一样
String s1 = encoder1.encode("mima");
String s2 = encoder2.encode("mima");

encode1在内存账号认证加密可以。
但是对于数据库,实现UserDetailService的只能用encode2,不然显示
That is not like BCrypt

猜你喜欢

转载自blog.csdn.net/chenbetter1996/article/details/85080790
今日推荐