如何将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
相关产品推荐
相关产品推荐

