You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.7中MockMvc自定义认证注入异常问题排查

问题原因与解决办法

为什么会出现这个问题?

1. 参数解析逻辑的优先级冲突

当控制器方法参数没有注解时,Spring MVC会通过Spring Security提供的参数解析器(比如AuthenticationPrincipalArgumentResolver)从SecurityContext里直接取出当前的认证对象,匹配到你的CustomAuthenticationToken类型后返回真实的MockCustomAuthenticationToken实例。

但如果给参数加上@Autowired,Spring会直接切换到依赖注入逻辑:它会去Spring容器里找CustomAuthenticationToken类型的Bean。而你只是在测试时通过@WithCustomAuthenticationToken把实例存入SecurityContext,并没有把它注册成容器Bean,所以Spring会为这个接口生成一个JDK动态代理(就是你看到的jdk.proxy2.$Proxy123),这个代理没有绑定任何真实实例数据,自然是空对象。

至于@ApiIgnore,它本身是Swagger的注解,正常不该影响参数解析,但如果你的项目里有自定义的参数解析逻辑对@ApiIgnore做了特殊处理,或者Swagger的解析器干扰了Spring MVC默认的参数解析优先级,会导致Spring误判为需要用DI逻辑处理这个参数,最终同样生成空代理。

2. 通用Authentication参数不受影响的原因

通用Authentication参数不管加不加注解都能正常工作,是因为:

  • 不加注解时,参数解析器直接从SecurityContext取到实例,类型匹配;
  • 加注解时,即使Spring尝试DI,容器里没有Authentication类型的Bean,但部分场景下Spring Security的参数解析器优先级更高,还是会从SecurityContext取数据,所以不会生成空代理。

解决办法

  1. 移除参数上的多余注解:
    CustomAuthenticationToken是从SecurityContext获取的认证对象,根本不需要@Autowired(它不是容器管理的Bean);如果是为了让Swagger忽略这个参数,别直接加@ApiIgnore在参数上,可以通过Swagger的全局配置或者接口级别的忽略规则来实现,避免干扰Spring的参数解析逻辑。

  2. 自定义参数解析器(可选):
    如果必须保留注解(比如有特殊业务需求),可以自定义一个HandlerMethodArgumentResolver,指定当参数是CustomAuthenticationToken且带有目标注解时,直接从SecurityContext中获取实例,覆盖Spring的DI解析逻辑。

  3. 排查Swagger配置:
    如果是@ApiIgnore导致的问题,检查项目里有没有自定义的Swagger参数处理器,确保它不会改变Spring MVC默认的参数解析优先级。

内容的提问来源于stack exchange,提问作者JayTheKay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:45:16