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

如何将Quarkus Rest Client与AWS Signature v4认证集成?

集成Quarkus响应式Rest Client与AWS Signature v4认证(对接AWS API Gateway)

要实现带@RegisterRestClient的Quarkus响应式Rest Client与AWS Signature v4认证的集成,核心是通过AWS SDK v2生成签名并注入HTTP请求头,以下是具体步骤:

1. 添加必要依赖

在构建文件中引入Quarkus响应式Rest Client和AWS SDK v2的认证、区域管理依赖:

Maven (pom.xml)

<dependencies>
    <!-- Quarkus响应式Rest Client -->
    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-rest-client-reactive</artifactId>
    </dependency>
    <!-- AWS SDK v2核心认证依赖 -->
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>auth</artifactId>
    </dependency>
    <!-- AWS区域管理 -->
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>regions</artifactId>
    </dependency>
</dependencies>

Gradle (build.gradle)

dependencies {
    implementation 'io.quarkus:quarkus-rest-client-reactive'
    implementation 'software.amazon.awssdk:auth'
    implementation 'software.amazon.awssdk:regions'
}

2. 实现AWS签名请求过滤器

创建ClientRequestFilter,利用AWS SDK v2的Aws4Signer计算签名,并将签名头注入Rest Client请求:

import io.quarkus.rest.client.reactive.ClientRequestFilter;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.core.MultivaluedMap;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.params.Aws4SignerParams;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;

import java.net.URI;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;

public class AwsSignatureFilter implements ClientRequestFilter {

    private final Aws4Signer signer = Aws4Signer.create();
    // 使用AWS默认凭证链:环境变量、本地配置文件、实例角色等
    private final DefaultCredentialsProvider credentialsProvider = DefaultCredentialsProvider.create();
    // 替换为你的API Gateway所在区域
    private final Region region = Region.of("us-east-1");
    // API Gateway对应的AWS服务名固定为execute-api
    private final String serviceName = "execute-api";

    @Override
    public void filter(ClientRequestContext requestContext) {
        // 转换JAX-RS请求为AWS SDK可处理的HTTP请求对象
        URI requestUri = requestContext.getUri();
        SdkHttpFullRequest.Builder sdkRequestBuilder = SdkHttpFullRequest.builder()
                .method(SdkHttpMethod.fromValue(requestContext.getMethod()))
                .uri(requestUri)
                .headers(convertJaxrsHeaders(requestContext.getHeaders()));

        // 构建签名参数
        Aws4SignerParams signerParams = Aws4SignerParams.builder()
                .credentials(credentialsProvider.resolveCredentials())
                .signingName(serviceName)
                .signingRegion(region)
                .signingClockOverride(Instant.now())
                .build();

        // 生成签名
        SdkHttpFullRequest signedRequest = signer.sign(sdkRequestBuilder.build(), signerParams);

        // 将签名后的请求头覆盖到原请求中
        signedRequest.headers().forEach((headerKey, headerValues) -> {
            requestContext.getHeaders().put(headerKey, headerValues);
        });
    }

    // 转换JAX-RS的多值头为AWS SDK需要的单值头映射
    private Map<String, String> convertJaxrsHeaders(MultivaluedMap<String, Object> jaxrsHeaders) {
        Map<String, String> sdkHeaders = new HashMap<>();
        jaxrsHeaders.forEach((key, values) -> {
            if (!values.isEmpty()) {
                sdkHeaders.put(key, values.get(0).toString());
            }
        });
        return sdkHeaders;
    }
}

3. 配置并注册Rest Client

在Rest Client接口上添加注解绑定签名过滤器:

import io.quarkus.rest.client.reactive.RegisterRestClient;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;

@RegisterRestClient(baseUri = "https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/YOUR_STAGE")
// 注册签名过滤器
@RegisterProvider(AwsSignatureFilter.class)
public interface AwsApiGatewayClient {

    @GET
    @Path("/your-target-endpoint")
    String getResource();
}

4. 补充配置(可选)

在application.properties中配置Rest Client基础URL和AWS区域(也可注入到过滤器实现动态配置):

# Rest Client基础URL(替代接口上的baseUri)
quarkus.rest-client."com.yourpackage.AwsApiGatewayClient".url=https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/YOUR_STAGE

# AWS区域(可通过@ConfigProperty注入到过滤器)
aws.region=us-east-1

关键注意事项

  • 凭证处理:DefaultCredentialsProvider遵循AWS凭证优先级规则,无需手动指定凭证,符合安全最佳实践。
  • 带请求体的请求:POST/PUT等带Body的请求需计算请求体SHA-256哈希并传入签名参数(可通过SdkBytes.fromInputStream读取流),否则签名验证失败;部分API允许使用UNSIGNED_PAYLOAD,但不推荐。
  • 区域与服务名:API Gateway服务名固定为execute-api,区域必须与部署区域完全一致,否则签名无效。
  • 响应式兼容性:该过滤器为同步实现,Quarkus响应式Rest Client会自动适配到Vert.x异步线程模型,无需额外处理异步逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:32:46