内存认证成功但数据库认证报错:No PasswordEncoder mapped for id "null"
解决Spring Security数据库认证报错:There is no PasswordEncoder mapped for the id "null"
嘿,这个问题我之前也碰到过!Spring Security 5+对密码的处理做了强制规范,咱们一步步来解决:
错误原因
从Spring Security 5开始,框架不再允许使用明文密码,所有密码必须通过PasswordEncoder进行加密存储和验证。你遇到的报错,是因为配置中没有指定对应的密码编码器,导致Spring找不到匹配的加密规则(默认的编码器ID为null,没有映射关系)。
而你之前的内存认证能成功,大概率是因为教程里的内存认证示例已经配置了编码器,或者用了加密后的密码字符串,所以没触发这个问题。
解决方案
1. 配置PasswordEncoder Bean
首先在你的SpringSecurityConfiguration类中,添加一个PasswordEncoder的Bean,推荐使用BCrypt加密(安全性高):
@Configuration @EnableWebSecurity public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter{ @Autowired private AuthenticationEntryPoint authenticationEntryPoint; // 添加PasswordEncoder Bean @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 其他配置... }
2. 在认证配置中关联编码器
接下来,在你配置数据库认证的地方(configure(AuthenticationManagerBuilder auth)方法),指定使用这个编码器:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 假设你用JDBC方式连接数据库 auth.jdbcAuthentication() .dataSource(dataSource) // 注入你的数据源 .usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?") .authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?") .passwordEncoder(passwordEncoder()); // 关键:关联上面定义的编码器 }
3. 确保数据库中的密码是加密后的字符串
最后,数据库里存储的密码不能是明文,必须是用BCrypt加密后的结果。你可以用这段简单的代码生成加密后的密码,再更新到数据库中:
public static void main(String[] args) { PasswordEncoder encoder = new BCryptPasswordEncoder(); // 替换成你的明文密码,生成加密后的字符串 System.out.println(encoder.encode("your-user-password")); }
把生成的加密字符串替换数据库中对应的明文密码即可。
这样配置后,Spring Security就能正确识别密码的加密规则,不会再报找不到编码器的错误啦!
内容的提问来源于stack exchange,提问作者Priyantha
相关产品推荐
相关产品推荐

