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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:01:29