如何在Spring Boot中Mock JwtDecoder进行认证控制器集成测试
解决Spring Boot OAuth2资源服务器Mock JwtDecoder的问题
你的场景是Spring Boot作为OAuth2资源服务器,依赖第三方授权服务器,测试时想通过Mock JwtDecoder用静态Bearer令牌离线验证,却遇到AuthenticationCredentialsNotFoundException,核心问题是Mock的JwtDecoder没被正确加载或调用,以下是可行的解决方案和排查点:
1. 实现测试专用的Mock JwtDecoder
创建只在测试环境生效的JwtDecoder实现,预定义静态令牌与JWT对象的映射:
@Component @Profile("test") public class MockJwtDecoder implements JwtDecoder { private static final Map<String, Jwt> TOKEN_JWT_MAP = Map.of( "STATIC_STRING", Jwt.withTokenValue("STATIC_STRING") .header("alg", "none") .claim("sub", "test-user-123") .claim("username", "test_user") .claim("authorities", List.of("ROLE_USER", "ROLE_ADMIN")) .build() ); @Override public Jwt decode(String token) throws JwtException { Jwt jwt = TOKEN_JWT_MAP.get(token); if (jwt == null) { throw new BadJwtException("无效的Mock令牌"); } return jwt; } }
2. 确保安全配置正确绑定JwtDecoder
在资源服务器安全配置中,显式注入并使用JwtDecoder,避免Spring自动生成默认实现:
@Configuration @EnableWebSecurity public class ResourceServerConfig { private final JwtDecoder jwtDecoder; public ResourceServerConfig(JwtDecoder jwtDecoder) { this.jwtDecoder = jwtDecoder; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwtConfigurer -> jwtConfigurer.decoder(jwtDecoder)) ); return http.build(); } }
3. 编写测试用例
测试类激活test profile,确保加载MockJwtDecoder,请求时携带静态Bearer令牌:
@SpringBootTest @AutoConfigureMockMvc @ActiveProfiles("test") class ProtectedControllerTest { @Autowired private MockMvc mockMvc; @Test void testAuthenticatedEndpoint() throws Exception { mockMvc.perform(get("/api/protected/info") .header(HttpHeaders.AUTHORIZATION, "Bearer STATIC_STRING")) .andExpect(status().isOk()) .andExpect(jsonPath("$.username").value("test_user")); } }
关键排查点
- Profile激活验证:必须在测试类上添加
@ActiveProfiles("test"),否则Spring会加载生产环境的JwtDecoder配置(比如指向Keycloak的地址),Mock实现不会生效。 - 安全配置绑定检查:如果在
oauth2ResourceServer().jwt()中没有显式指定decoder(jwtDecoder),Spring会自动根据配置文件创建JwtDecoder实例,覆盖你的Mock Bean。 - 令牌格式正确性:请求头必须严格遵循
Authorization: Bearer STATIC_STRING格式,注意Bearer后有空格,令牌字符串要和MockJwtDecoder中预定义的完全一致。 - Bean注入验证:可以在MockJwtDecoder的构造器中添加日志,或者在测试类中
@Autowired该Bean,确认它被正确加载。
内容的提问来源于stack exchange,提问作者Nikita Pavlovski
相关产品推荐
相关产品推荐

