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

本文详细解析了从Spring Security 4到5的密码管理机制变化,特别是密码加密的要求增强。针对升级后的常见错误,提供了具体的代码示例,演示如何在Spring Security 5中正确配置密码加密,避免因明文密码存储引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错误解释

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

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 10MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值