直接从 API Gateway 中的 HTTP API 将 putObject 写入 S3

问题描述

我的目的是在 Amazon API Gateway 上创建一个 HTTP API,通过 S3 API 使用 PutObject 操作将文件写入 S3(中间不调用 Lambda)。这是 PutObject 请求语法:https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#API_PutObject_RequestSyntax

我不确定这在技术上是否可行,并且我在 Postman 中收到 403 Forbidden: ForbiddenException 响应。

到目前为止我有

  1. 创建了 S3 存储桶(配置了 CORS)
  2. 在 API Gateway 中创建了 HTTP API(配置了 CORS),使用“putObject”POST 操作
  3. 在 HTTP API 上配置了到 https://[s3-bucket-name].s3.us-east-1.amazonaws.com 的集成
  4. 创建对 HTTP API“调用 URL”的 Postman 请求,并在标头上设置“Host”和“x-apigw-api-id”

ForbiddenException 显然表明存在权限问题,无论是 HTTP API 还是其背后的 S3 API。我确实在 HTTP API 上配置了一个 Cloudwatch 日志组,它没有显示任何条目,所以它似乎是一个 HTTP API 访问问题。

我还怀疑我需要将参数映射添加到 HTTP API 以将所有必要的标头传递给 S3 putObject 操作。

我的问题是:

  1. 这种类型的 HTTP API 是否可以直接集成到 S3?
  2. 服务发出 403 Forbidden 响应的可能原因是什么?
  3. 我是否会在 HTTP API 集成配置中使用“附加”参数映射来添加标准 S3 API 参数(并避免将它们暴露给客户端)?

解决方法

我自己设法解决了这个问题。回答我自己的问题:

这种类型的 HTTP API 是否可以直接集成到 S3?

是的。在我的 HTTP API 上,我使用了指向 S3 服务端点的 HTTP PUT 集成(包括端点中的存储桶名称不正确)。

服务发出 403 Forbidden 响应的可能原因是什么?

我没有从邮递员那里得到请求,但是,当我从浏览器发出请求时,它起作用了。在通过 navigator.beacon() 将其作为请求发送到 HTTP API 端点 URL 之前,我必须在 Javascript 中创建一个 Blob。

我是否会在 HTTP API 集成配置中使用“附加”参数映射来添加标准 S3 API 参数(并避免将它们暴露给客户端)?

我确实必须使用参数映射才能从 API Gateway 获取 S3 PutObject 请求。我的配置如下所示。

{{3}}

编辑:我在此方法中发现了一个问题:HTTP API 不允许在参数映射中添加某些与安全相关的标头。我试图设置 header.x-amz-acl: 'bucket-owner-full-control' 但我收到以下错误消息:

指定的映射表达式无效:验证结果:警告:[],错误:[头 x-amz-acl 上的操作受到限制]

似乎无法在 HTTP API 中修改任何与安全相关的 S3 API 标头。这是直接调用 S3 API 的一个主要问题,因为这意味着为了运行,S3 存储桶需要是公开的。