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

Spring @WebMvcTest测试OpenAPI生成的@PreAuthorize控制器返回401异常

问题分析与解决方案

问题原因

在@WebMvcTest切片测试环境下,方法级安全的核心组件未被正确初始化,导致@PreAuthorize注解的权限校验逻辑没有执行。@WebMvcTest默认仅加载Web层相关Bean(如@RestController),不会自动导入全局的Spring Security配置类(即你的RestSecurityConfiguration),而@EnableMethodSecurity注解正是在这个配置类中启用方法安全的关键——它负责注册MethodSecurityInterceptor等切面组件,没有这些组件,@PreAuthorize的校验就不会生效。

此时虽然你传入了已认证的Authentication对象,但由于方法安全校验未触发,结合OAuth2资源服务器的配置逻辑,最终返回了401而非预期的403。而改用HttpSecurity的requestMatchers配置时,权限校验是在过滤器链层面执行的,只要SecurityFilterChainBean被加载就能正常工作,因此测试可以通过。

解决方案

方案1:导入全局Security配置类

在测试类中显式导入RestSecurityConfiguration,确保@EnableMethodSecurity和相关安全组件被加载:

@WebMvcTest(PingController.class)
@Import({PingApiController.class, RestSecurityConfiguration.class})
class PingControllerTest extends AbstractControllerTest {

    @MockBean
    private JwtAuthConverter jwtAuthConverter; // Mock配置类依赖的JwtAuthConverter

    // ... 测试代码
}

方案2:在测试类中直接启用方法安全

如果不想导入完整的全局配置,可以在测试类上直接添加@EnableMethodSecurity注解,单独启用方法级安全:

@WebMvcTest(PingController.class)
@Import({PingApiController.class})
@EnableMethodSecurity
class PingControllerTest extends AbstractControllerTest {

    // ... 测试代码
}

方案3:确认认证对象权限格式

你的测试代码中已经将权限转为ROLE_wrong-role,这与hasRole('ping')自动添加ROLE_前缀的逻辑匹配,这部分无需修改,只需确保方法安全生效后,该权限校验逻辑能被触发。

验证

修改后重新运行测试,@PreAuthorize的权限校验会正常执行,当角色不匹配时,会返回预期的HTTP 403状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:44:53