如何为每个@WebMvcTest切片测试自动加载SecurityFilterChain
此前通过继承WebSecurityConfigurerAdapter实现应用的Web安全配置,参考官方入门指南的写法配置非常简便:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // 按需重写所需方法 }
从Spring Boot 2.7.0、Spring Security 5.7.x版本开始,WebSecurityConfigurerAdapter被正式废弃,官方给出的推荐替代方案是自定义声明SecurityFilterChain类型的@Bean。
版本迁移过程中遇到问题:声明SecurityFilterChain的@Configuration类,无法像此前基于WebSecurityConfigurerAdapter的配置类那样,在@WebMvcTest切片测试中自动生效,目前只能采用临时方案,在每个@WebMvcTest测试类中手动导入该配置类。
已知切片测试的上下文加载规则:Spring Boot 2.7版本前通过META-INF/spring.factories管理自动配置,2.7版本后调整为META-INF/spring/<slice-name>.imports管理;当前使用的Spring Boot 2.7.1版本中,WebMvc切片配置存放在官方对应的AutoConfigureWebMvc.imports文件中,需要实现将包含SecurityFilterChain的自定义@Configuration自动纳入现有@WebMvcTest切片加载范围的效果。
有两种稳定可落地的实现方案,不需要在每个测试类上重复编写导入注解:
- 方案一:公共测试基类统一导入
在测试源码目录编写@WebMvcTest测试的通用基类,在基类上通过@Import(自定义安全配置类.class)注解引入安全配置,所有Web层切片测试类直接继承该基类即可自动加载安全规则,不需要单独配置。 - 方案二:遵循Spring Boot 2.7+的切片扩展规则注册配置(无侵入)
这是和官方原生加载逻辑完全一致的实现方式,不需要修改任何现有测试代码:- 在项目的测试资源目录下创建层级路径
META-INF/spring/ - 在该路径下新建文件,文件名为
org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports - 文件内仅填写自定义安全配置类的全限定类名,每行一个,例如
com.example.project.config.SecurityConfig
配置完成后,所有@WebMvcTest启动的切片上下文都会自动扫描并加载该配置类。
- 在项目的测试资源目录下创建层级路径
避坑提示:如果你的正式安全配置依赖了Service、DAO等Web切片不会默认加载的Bean,建议单独拆分一个仅保留Web层安全规则的测试专用配置类放到上述imports文件中,或者在正式配置的对应Bean上添加
@ConditionalOnMissingBean注解,避免切片测试启动时抛出找不到依赖Bean的错误。
内容的提问来源于stack exchange,提问作者Kirill

