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

在项目开发中遇到一个登录时的NetworkError问题,通过分析发现是SpringSecurity在找寻PasswordEncoder时出错。尽管在配置文件中已经指定了customMd5PasswordEncoder,但@Autowired无法实例化。问题的根源在于启动类中过度定义了scanBasePackages,这导致某些包未被扫描到。移除该配置后,问题得到解决,Autowired可以正常注入PasswordEncoder。

问题描述

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

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

问题定位

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

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

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

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

解决方案 

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

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

启动类位置如图,众所周知默认扫描的是当前包及其子包的内容

而定义了scanBasePackages导致默认扫描规则失效,有其他的包没有被扫描到。所以其实不需要重复定义,我们直接删掉就好。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值