Spring Boot中API Key认证的测试调整方案
问题:Spring Boot API Key认证端点测试返回403 Forbidden的解决方法
场景与代码
我有一个Spring Boot应用,其中一个端点通过API Key进行认证,认证配置代码如下:
@Configuration @EnableWebSecurity @Order(1) public class AuthConfiguration { public static final String API_KEY_VALUE = "skrdgvsnelrkv"; public static final String API_KEY_HEADER = "API_KEY"; @Value(API_KEY_HEADER) private String principalRequestHeader; @Value(API_KEY_VALUE) private String principalRequestValue; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { AuthFilter apiKeyFilter = new AuthFilter(principalRequestHeader); apiKeyFilter.setAuthenticationManager(new AuthenticationManager() { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String principal = (String) authentication.getPrincipal(); if (!principalRequestValue.equals(principal)) { throw new BadCredentialsException( "The API key was not found or not the expected value." ); } authentication.setAuthenticated(true); return authentication; } }); http.antMatcher(Endpoints.VALIDATE) .csrf() .disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilter(apiKeyFilter) .authorizeRequests() .anyRequest() .authenticated(); return http.build(); } }
此前针对该端点的测试用例现在返回403 Forbidden错误,测试代码如下:
@AutoConfigureTestEntityManager @SpringBootTest @ContextConfiguration(classes = { TestContext.class }) @TestPropertySource(properties = { "spring.main.allow-bean-definition-overriding=true" }) @AutoConfigureMockMvc class ControllerTest { @Autowired private MockMvc mockMvc; @Test void callingValidateEndpointWithValidFileShouldReturnResponseWithStatusOk() throws Exception { MockMultipartFile file = MockMultipathFileBuilder.buildFromFilePath(TestFiles.VALID_FILE); mockMvc.perform(MockMvcRequestBuilders.multipart(Endpoints.VALIDATE).file(file)) .andExpect(status().isOk()); } }
解决方案
测试请求未携带认证所需的API Key请求头,导致被安全过滤器拦截返回403。只需在请求中添加对应的API Key头即可通过认证。
修改后的测试代码:
@AutoConfigureTestEntityManager @SpringBootTest @ContextConfiguration(classes = { TestContext.class }) @TestPropertySource(properties = { "spring.main.allow-bean-definition-overriding=true" }) @AutoConfigureMockMvc class ControllerTest { @Autowired private MockMvc mockMvc; @Test void callingValidateEndpointWithValidFileShouldReturnResponseWithStatusOk() throws Exception { MockMultipartFile file = MockMultipathFileBuilder.buildFromFilePath(TestFiles.VALID_FILE); mockMvc.perform(MockMvcRequestBuilders.multipart(Endpoints.VALIDATE) .file(file) // 添加API Key认证头 .header(AuthConfiguration.API_KEY_HEADER, AuthConfiguration.API_KEY_VALUE)) .andExpect(status().isOk()); } }
补充说明
- 直接复用
AuthConfiguration类中定义的常量,避免硬编码,保证测试与生产环境的配置一致性 - 若测试环境使用独立的API Key配置,可通过
@Value注入测试环境的配置值替换常量,例如:
然后在请求头中使用@Value("${api.key}") private String testApiKey;testApiKey即可。
内容的提问来源于stack exchange,提问作者Kira Resari
相关产品推荐
相关产品推荐

