首页 > 解决方案 > 通过 API 网关 MethodNotAllowed 使用自定义端点的 S3 预签名 URL

问题描述

我正在尝试为具有自定义端点的 S3 存储桶使用预签名的 url。我看起来很接近,但我不断收到 Method Not Allowed 错误。这就是我所在的地方。

我有一个将端点连接到 Lambda 函数的 API 网关。除其他外,该函数会生成一个预签名的 url。像这样,

var s3 = new AWS.S3({
    endpoint: 'custom.domain.com/upload',
    s3BucketEndpoint: true,
    signatureVersion: 'v4'
});

//...

s3.getSignedUrl('putObject', {
    ACL: 'bucket-owner-full-control',
    Bucket: process.env.S3_BUCKET_NAME,
    ContentType: "image/png",
    Key: asset.id + ".png"
};

此代码成功返回一个 url,其中包含所有正确的查询参数、正确的键名,并且该 url 指向我的端点。但是,在尝试上传时,我收到以下错误:

MethodNotAllowed不允许针对此资源使用指定的方法。PUTSERVICE[request id was here][host id was here]

如果我从我的 S3 配置中删除我的自定义端点声明,我会收到一个标准域前缀的预签名 url,并且上传工作正常。

关于我的设置的其他说明。

  1. 我已将 API Gateway 上的 /upload 资源配置为 PUT 方法的 S3 直通。
  2. 我在需要的地方启用了 CORS。在存储桶和我的 API 上。我已经确认 CORS 很好,因为浏览器通过了检查。
  3. 我已经制定了我的政策。lambda 函数可以从我的 VPC 访问 Internet,它具有完整的 S3 访问权限,并且它与 S3 和 API 网关都具有信任关系。此执行角色在资源之间共享。
  4. 我正在使用 axios 包通过 PUT 上传文件。
  5. 我添加了一个 CloudTrail 日志,但它报告的错误与浏览器完全相同...
  6. 暂时公开我的存储桶没有任何区别。
  7. 我试图将查询字符串添加到 API Gateway 请求/响应集成中,但没有成功。
  8. 我已将必要的内容类型标头添加到请求和预签名的 url 配置中。
  9. 我用谷歌搜索了这件事。

我错过了什么吗?这可能吗?我计划暂时禁用我的自定义端点并继续使用默认的预签名 url,但从长远来看,我想要自定义端点。在最坏的情况下,我可能会为一些 AWS 支持付费。

谢谢您的帮助!

标签: node.jsamazon-web-servicesamazon-s3pre-signed-url

解决方案


我找不到说明预签名 URL 支持代理(替代/自定义域)的文档。IMO 用于从 API 网关(无论您是否代理 S3)对 AWS 资源的请求进行身份验证和授予访问权限的用例将是使用带有 lambda 的 API 网关授权方来允许请求承担 IAM 角色有权访问 AWS 资源(在这种情况下,将 OBJECT 放在 s3 存储桶上)

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html


推荐阅读