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

Quarkus后端调用AWS IoT Core设备影子API时的认证头添加问题

在Quarkus中为AWS IoT Core设备影子API请求添加认证头

AWS IoT Core的设备影子API要求使用SigV4签名进行认证,这是AWS服务的标准HTTP认证方式。下面针对你的Quarkus代码,提供两种可行的实现方案,优先推荐基于Quarkus官方扩展的简化方案。

方案一:使用Quarkus Rest Client AWS扩展(推荐)

Quarkus提供了专门的扩展来自动处理AWS服务的SigV4签名,无需手动实现复杂的签名逻辑。

1. 添加依赖

在你的pom.xml(Maven)或build.gradle(Gradle)中添加扩展依赖:

<!-- Maven -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest-client-aws</artifactId>
</dependency>

2. 修改Rest Client接口

修正原接口中查询参数的不规范写法,并添加AWS签名注解:

import io.smallrye.mutiny.Uni;
import io.quarkus.rest.client.aws.AwsSign;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import javax.json.JsonObject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@Path("/things/abc")
@Produces(MediaType.APPLICATION_JSON)
@RegisterRestClient(baseUri = "https://a144gttuytyty10wv7-ats.iot.us-east-1.amazonaws.com")
// 添加SigV4签名配置,指定IoT数据服务名和区域
@AwsSign(service = "iotdata", region = "us-east-1")
public interface OrganizationProxy {

    // 用@QueryParam传递影子名称,替代原Path中的硬编码参数
    @GET
    @Path("/shadow")
    Uni<JsonObject> getOrg(@QueryParam("name") String shadowName);
}

3. 更新资源类调用

调整调用逻辑,传入影子名称参数:

import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.json.JsonObject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/organizations")
@ApplicationScoped
public class OrganizationResource {

    @Inject
    @RestClient
    OrganizationProxy organizationProxy;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<JsonObject> get() {
        return organizationProxy.getOrg("shadow-version-1");
    }
}

4. 配置AWS凭证

Quarkus会自动从以下渠道加载AWS凭证(优先级从高到低):

  • 环境变量(AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY)
  • 系统属性
  • ~/.aws/credentials文件
  • IAM角色(如果部署在AWS ECS/EKS/EC2等服务上)

本地开发时,可在application.properties中临时配置(生产环境不建议硬编码):

quarkus.aws.region=us-east-1
# 可选:指定凭证类型,默认会自动探测
quarkus.aws.credentials.type=default

方案二:手动实现SigV4签名过滤器

如果无法使用官方扩展,可通过JAX-RS客户端过滤器手动生成SigV4签名头。

1. 添加AWS SDK依赖

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>auth</artifactId>
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>regions</artifactId>
</dependency>

2. 实现签名过滤器

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.ext.Provider;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
import java.net.URI;
import java.util.HashMap;

@Provider
public class AwsSigV4Filter implements ClientRequestFilter {

    private final Aws4Signer signer = Aws4Signer.create();
    private final DefaultCredentialsProvider credentialsProvider = DefaultCredentialsProvider.create();
    private final Region region = Region.US_EAST_1;
    private final String serviceName = "iotdata";

    @Override
    public void filter(ClientRequestContext requestContext) {
        URI uri = requestContext.getUri();
        // 构建AWS签名所需的请求对象
        SdkHttpFullRequest.Builder requestBuilder = SdkHttpFullRequest.builder()
                .method(SdkHttpMethod.fromValue(requestContext.getMethod()))
                .uri(uri)
                .headers(new HashMap<>(requestContext.getHeaders()));

        // 生成签名
        SdkHttpFullRequest signedRequest = signer.sign(
                requestBuilder.build(),
                credentialsProvider.resolveCredentials(),
                serviceName,
                region
        );

        // 替换请求头为签名后的头
        requestContext.getHeaders().clear();
        signedRequest.headers().forEach((key, values) -> requestContext.getHeaders().put(key, values));
    }
}

3. 注册过滤器到Rest Client

在OrganizationProxy接口上添加过滤器注册:

@RegisterRestClient(baseUri = "https://a144gttuytyty10wv7-ats.iot.us-east-1.amazonaws.com")
@RegisterProvider(AwsSigV4Filter.class) // 注册签名过滤器
public interface OrganizationProxy {
    // 接口方法同方案一
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:47:49