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

Quarkus安全端点集成测试:自定义拦截器场景下的测试方案

自定义注解+拦截器的Quarkus端点安全集成测试问题

问题背景

我有一个Quarkus应用,通过自定义注解与拦截器实现端点安全控制,相关代码如下:

自定义注解

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface PermitRole {
}

绑定注解的拦截器

@Interceptor
@PermitRole
public class LiveTraderRolesAuthorization { 
   @Inject
   HttpHeaders headers;

   @Inject
   JWTTokenParser jwtTokenParser;

   @AroundInvoke
   public Object authorize(InvocationContext context) throws Exception {
       // 此处使用nimbus-jose解析Authorization头中的JWT令牌并设置授权标识
      if(authorized) {
        return context.proceed();
      }
      // 补充未授权处理逻辑(示例)
      throw new ForbiddenException("无访问权限");
    }
}

控制器方法

@GET
@PermitRole
@Produces(MediaType.APPLICATION_JSON)
public RestResponse<MResponse> getSome(@PathParam("Id") String Id) {
    //业务逻辑
}

问题

添加该自定义注解后,控制器集成测试失败。虽然可以通过Mock JWTTokenParser 返回模拟claims来绕过,但我希望找到一种更合理的方式,能将拦截器与控制器一起做集成测试,完整验证拦截器和令牌解析的真实逻辑(和生产环境运行逻辑一致)。

注:我使用nimbus-jose-jwt库解析JWT令牌,未使用Quarkus专属的JWT组件。

解决方案

1. 生成真实有效的测试JWT令牌

直接用nimbus-jose-jwt库生成符合你校验逻辑的JWT令牌,确保测试时走真实的解析流程:

// 测试类中的JWT生成工具方法
private String generateValidTestJwt() throws JOSEException {
    // 使用和生产环境一致的签名算法、密钥
    JWSSigner signer = new MACSigner("your-test-secret-key"); // 替换为实际密钥或从配置读取
    JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
            .subject("test-user")
            .claim("roles", Arrays.asList("allowed-role")) // 带上拦截器校验需要的角色声明
            .expirationTime(new Date(System.currentTimeMillis() + 3600000)) // 设置过期时间
            .build();

    SignedJWT signedJWT = new SignedJWT(
            new JWSHeader(JWSAlgorithm.HS256),
            claimsSet);
    signedJWT.sign(signer);
    return signedJWT.serialize();
}

2. 在集成测试中携带真实令牌发起请求

用Quarkus自带的@QuarkusTest结合RestAssured发起请求,带上生成的JWT:

@QuarkusTest
public class YourControllerTest {

    @Test
    public void testGetSome_ValidToken_ReturnsSuccess() throws JOSEException {
        String validJwt = generateValidTestJwt();

        given()
                .header("Authorization", "Bearer " + validJwt)
                .pathParam("Id", "test-id")
        .when()
                .get("/your-endpoint/{Id}")
        .then()
                .statusCode(200);
    }

    @Test
    public void testGetSome_InvalidToken_ReturnsForbidden() {
        given()
                .header("Authorization", "Bearer invalid-token-string")
                .pathParam("Id", "test-id")
        .when()
                .get("/your-endpoint/{Id}")
        .then()
                .statusCode(403);
    }

    @Test
    public void testGetSome_NoToken_ReturnsForbidden() {
        given()
                .pathParam("Id", "test-id")
        .when()
                .get("/your-endpoint/{Id}")
        .then()
                .statusCode(403);
    }
}

3. 统一配置测试环境密钥

如果生产环境的JWT密钥是从配置读取的,在application-test.properties中配置测试专用密钥,确保测试与生产的逻辑一致性:

# application-test.properties
jwt.signing.secret=your-test-secret-key

然后在JWTTokenParser中通过@ConfigProperty注入密钥,避免硬编码。

方案优势

  • 完全覆盖真实的令牌解析、签名验证、声明校验全流程,不会遗漏Mock忽略的边界场景(比如令牌过期、签名错误)
  • 测试逻辑与生产运行逻辑完全对齐,能更早发现集成层面的问题
  • 无需维护Mock逻辑,减少测试代码的复杂度和维护成本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:33:31