解决security报错 - There is no PasswordEncoder mapped for the id "null"

165 阅读1分钟

问题描述

在最近写项目的时候遇到一个小bug,访问登录界面时提交会显示Network Error

图片.png 此时想通过knife4j测试下后端登录接口,然而在登录springsecurity页面时输入正确的账号密码,提交后报如下错误

图片.png

问题定位

这个问题其实不难,通俗点讲就是springsecurity需要一个密码器来进行加密、解密。其中查找官方文档我们知道密码的存储格式是“{id}…”.前面的id是加密方式,后面跟着的是加密后的密码。所以,当从数据库获取到密码时,会先找到定义加密方式,如果找不到就认为id是null。所以说会报错。

然而,在我的代码中确实有定义PasswordEncoder,如下在security的config文件中:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // 指定UserDetailService和加密器
    auth.userDetailsService(userDetailsService).passwordEncoder(customMd5PasswordEncoder);
}

这就很奇怪了,已经指明了还报错。那只可能是一种情况,当前传递的这个customMd5PasswordEncoder在程序中找不到🙃 回顾前面的@Autowired,果然找不到实例!!!

图片.png

解决方案

通过排查代码,发现错误出在启动类上,如下我定义了scanBasePackages

@SpringBootApplication(scanBasePackages = {"com.oa.auth","com.oa.process"})
public class ServiceOAApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceOAApplication.class);
    }
}

启动类位置如图,众所周知默认扫描的是当前包及其子包的内容
Snipaste_2023-06-01_17-10-24.png
而定义了scanBasePackages导致默认扫描规则失效,有其他的包没有被扫描到。所以其实不需要重复定义,我们直接删掉就好

@SpringBootApplication()
public class ServiceOAApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceOAApplication.class);
    }
}

此时发现config中@Autowired不再报错,问题解决,在此记录一下