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

Spring TestRestTemplate POST请求Basic Auth失效返回302问题

解决TestRestTemplate POST接口302重定向问题

看起来你的GET接口用Basic Auth能正常测试,但POST接口却返回302重定向到登录页,我帮你梳理下几个大概率的原因和对应的解决办法:

1. POST请求缺少JSON格式请求头

你当前的POST测试代码里,构造HttpEntity时只传了请求体,没有指定Content-Type: application/json。而控制器的@PostMapping配合@RequestBody是期望接收JSON格式请求的,Spring如果无法解析请求体,可能会触发异常,进而被安全过滤器拦截导致重定向。

修改测试代码,加上正确的请求头:

@Test
void filteredSearch() {
    // 构造JSON请求头
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    // 组装带请求头的请求实体
    HttpEntity<FilteredSearchRequest> requestEntity = new HttpEntity<>(new FilteredSearchRequest(), headers);
    
    val reply = testRestTemplate.withBasicAuth("test", "test")
            .exchange("/reference_data/search", HttpMethod.POST, requestEntity, new ParameterizedTypeReference<List<Map<String, Object>>>() {});
            
    System.out.println(reply);
    assertEquals(HttpStatus.OK, reply.getStatusCode());
}

2. ADFS安全配置与测试环境内存用户冲突

你的AdfsSecurityConfiguration默认是开启的(matchIfMissing = true),而测试环境配置了spring.security.user的内存用户,这两者的认证逻辑可能存在冲突:

  • AdfsConfigurer大概率配置了ADFS相关的认证(比如OAuth2或SAML),而Basic Auth是Spring Security的默认内存认证,过滤器执行顺序可能导致POST请求时Basic Auth未被正确识别。

这里有两种解决思路:

思路一:测试时排除ADFS安全配置

在测试类上直接排除AdfsSecurityConfiguration,让Spring Security使用默认的内存认证:

@SpringBootTest
@EnableAutoConfiguration(exclude = AdfsSecurityConfiguration.class)
class YourControllerTest {
    // 你的测试代码...
}

思路二:让ADFS配置兼容测试环境的Basic Auth

修改AdfsSecurityConfiguration,当处于test profile时,添加Basic Auth支持:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    if (!isRunningLocally()) {
        http.requiresChannel().anyRequest().requiresSecure();
    }
    
    // 测试环境下启用Basic Auth
    if (environment.acceptsProfiles(Profiles.of("test"))) {
        http.httpBasic();
    }
    
    http.apply(adfsConfigurer).and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and().authorizeRequests()
            .requestMatchers(EndpointRequest.to("keepalive", "info", "health", "env"), EndpointRequest.toLinks())
            .permitAll().anyRequest().authenticated().and().csrf().disable();
}

// 同时更新本地环境判断,把test profile也包含进来
private boolean isRunningLocally() {
    return environment.acceptsProfiles(Profiles.of("default", "test"));
}

3. 测试环境被强制要求HTTPS

你的isRunningLocally()方法只判断了default profile,但测试用的是test profile,所以这个方法会返回false,进而执行http.requiresChannel().anyRequest().requiresSecure();,强制所有请求使用HTTPS。而TestRestTemplate默认用HTTP请求,会被重定向,最终导致跳转到登录页。

解决办法就是把test profile加入本地环境的判断,让测试环境不强制HTTPS:

private boolean isRunningLocally() {
    return environment.acceptsProfiles(Profiles.of("default", "test"));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:22:36