Spring WebFlux Security允许路由单元测试返回401未授权问题排查
尝试测试/cat路由(返回对象数组)时,预期状态码为200 OK,但实际返回401 Unauthorized。同时测试控制台打印了自动生成的安全密码,尽管已在Security配置中禁用了表单登录和HTTP Basic认证。
测试类代码
@RunWith(SpringRunner.class) @WebFluxTest(value = CatController.class) class ContentManagementTestApplicationTests { @Autowired ApplicationContext context; @Autowired private WebTestClient webTestClient; @MockBean CatRepository catRepository; @BeforeEach public void setup(){ webTestClient=WebTestClient.bindToApplicationContext(context) .apply(SecurityMockServerConfigurers.springSecurity()) .configureClient() .build(); } @Test void contextLoads() { } @Test public void getApprovedCats(){ webTestClient.get() .uri("/cat") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk(); } }
Security配置类代码
@Bean SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, AuthConverter jwtAuthConverter, AuthManager jwtAuthManager){ AuthenticationWebFilter jwtFilter = new AuthenticationWebFilter(jwtAuthManager); jwtFilter.setServerAuthenticationConverter(jwtAuthConverter); return http .csrf().disable() .authorizeExchange() .pathMatchers(HttpMethod.GET,"/cat").permitAll() .anyExchange().authenticated() .and() .addFilterAt(jwtFilter, SecurityWebFiltersOrder.AUTHORIZATION) .formLogin().disable() .httpBasic().disable() .build(); }
报错信息
java.lang.AssertionError: Status expected:<200 OK> but was:<401 UNAUTHORIZED> Expected :200 OK Actual :401 UNAUTHORIZED
解决方案
导入自定义安全配置类:
@WebFluxTest默认仅加载指定控制器,不会自动引入全局安全配置。需在测试类添加@Import注解加载ApplicationSecurityConfig:@RunWith(SpringRunner.class) @WebFluxTest(value = CatController.class) @Import(ApplicationSecurityConfig.class) // 新增导入 class ContentManagementTestApplicationTests { // 原有代码不变 }调整过滤器顺序:自定义JWT过滤器当前添加在
AUTHORIZATION阶段,会导致权限校验先于认证执行。改为AUTHENTICATION阶段确保认证优先:.addFilterAt(jwtFilter, SecurityWebFiltersOrder.AUTHENTICATION) // 修改过滤器顺序排除自动安全配置:控制台生成默认密码说明Spring Security自动配置类仍在生效,测试类中排除相关自动配置:
@RunWith(SpringRunner.class) @WebFluxTest( value = CatController.class, excludeAutoConfiguration = {SecurityAutoConfiguration.class, ReactiveSecurityAutoConfiguration.class} ) @Import(ApplicationSecurityConfig.class) class ContentManagementTestApplicationTests { // 原有代码不变 }验证路径匹配准确性:确认
pathMatchers(HttpMethod.GET,"/cat")的路径与测试请求的/cat完全一致,无前缀、大小写等差异。
内容的提问来源于stack exchange,提问作者Diego Mcrae
相关产品推荐
相关产品推荐

