用于访问无法从自定义域访问的 S3 私有内容的签名 URL

Posted

技术标签:

【中文标题】用于访问无法从自定义域访问的 S3 私有内容的签名 URL【英文标题】:Signed URLs for accessing S3 private content not accessible from custom domain 【发布时间】:2014-11-06 14:42:28 【问题描述】:

我正在签署 S3 上可用的私有资源,以使其暂时公开可用。这是我用 v3 版本的协议签署 URL 后得到的:

http://s3.amazonaws.com/some.bucket.com/stuff/123/my.doc?AWSAccessKeyId=ABCDEFGHIJK1LMNOP1WE&Expires=1410526534&Signature=r6helf9WA0%2FOSvwbuwTqGJJ6u3c%3D

假设我想用其他域替换 s3.amazonaws.com,为此我在我的 DNS 设置中输入新的 CNAME 条目(我将 my.stuff.net 映射为 s3.amazonaws.com 的别名。) .如果我现在尝试查询以下 URL,我会从亚马逊那里得到关于签名验证失败的详细描述。

http://my.stuff.net/some.bucket.com/stuff/123/my.doc?AWSAccessKeyId=ABCDEFGHIJK1LMNOP1WE&Expires=1410526534&Signature=r6helf9WA0%2FOSvwbuwTqGJJ6u3c%3D

v3 签名不包括主机名,所以我的猜测是签名实际上是正确的,但亚马逊会验证请求来自哪个域并拒绝所有不是来自 s3.amazonaws.com 的内容。

有人知道我的猜测是否正确以及是否有解决方法吗?

【问题讨论】:

【参考方案1】:

存储桶名称必须与CNAME相同

http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html

因此,您通过 CNAME 指向 bucketname.s3.amazonaws.com 的主机名必须与存储桶名称相同。如果存储桶的名称不是有效的 DNS 名称,则它不起作用。

如果你走那条路线,那么你还需要从路径的开头删除存储桶名称(不是从字符串到签名,而是从 URL),因为 S3 对发送的 Host: 标头做出反应由浏览器判断请求URI路径是否以bucket名称开头。

这是在不使用代理将请求重写到 S3 的过程中的唯一方法,如果上述不适用,您可以考虑另一种选择。

【讨论】:

http://xsome.bucket.com.s3.amazonaws.com/stuff/123/my.doc?AWS... 将成功返回与http://s3.amazonaws.com/some.bucket.com/stuff/123/my.doc?AWS... 相同的结果。我想说亚马逊只是在签名验证(包括完整路径)之前重写 URL。就我而言,我会将文档中的那句话替换为“CNAME 必须与存储桶名称相同”。我同意在代理上重写 URL 是唯一合理的做法。

以上是关于用于访问无法从自定义域访问的 S3 私有内容的签名 URL的主要内容,如果未能解决你的问题,请参考以下文章

Amazon s3:“阻止公共访问”设置以允许使用签名 URL 进行公共读取私有写入

如何使用预设策略加密 Amazon CloudFront 签名以进行私有内容访问

即使 IAM 策略授予访问权限,Web 应用程序也无法访问私有 s3 文件

AWS 静态网站 + 云端签名 cookie

由于授权,无法访问 S3 预签名 URL [重复]

Elastic beanstalk 实例无法访问私有 S3 文件