如何在不公开存储桶名称的情况下为自定义域生成 S3 预签名 URL

How to generate an S3 pre-signed URL for a custom domain without exposing bucket name

我有一个存储桶 my-bucket-name,我想授予对 folder-name 中某些 file.pdf 的临时访问权限。至于默认我得到下一个 link 使用 boto3:

https://my-bucket-name.s3.amazonaws.com/folder-name/file.pdf?AWSAccessKeyId=<key>&Signature=<signature>&x-amz-security-token=<toke>&Expires=<time>

但我还有一个 DNS 别名,my.address.com 映射到 my-bucket-name.s3.amazonaws.com。当然,如果我直接使用它,我会从亚马逊获得 SignatureDoesNotMatch。所以我正在使用下一个代码生成预签名 link:

from botocore.client import Config

kwargs = {}
kwargs['endpoint_url'] = f'https://my.address.com'
kwargs['config'] = Config(s3={'addressing_style': 'path'})

s3_client = boto3.client('s3', **kwargs)
url = s3_client.generate_presigned_url(ClientMethod='get_object',
                                       Params={
                                          'Bucket': 'my-bucket-name',
                                          'Key': 'folder-name/file.pdf'
                                       },
                                       ExpiresIn=URL_EXPIRATION_TIME)

结果returns我下一个link:

https://my.address.com/my-bucket-name/folder-name/file.pdf?AWSAccessKeyId=<key>&Signature=<signature>&x-amz-security-token=<toke>&Expires=<time>

这有两个问题:

<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>

就是这些问题:

  1. 是否可以在不公开存储桶名称的情况下实现可行的 link?
  2. 我已经读到一些关于自定义域只能用于 HTTP 而不是 HTTPS 访问的信息,这是真的吗?这种情况怎么办?
  3. DNS 别名不是我创建的,所以我不确定它是否有效或设置是否正确,我应该如何 check/ask 验证它是否适用于 s3?

目前我有点迷失在 Amazon 文档中。我也是 AWS 的新手。

据我所知,如果不公开存储桶名称,就无法获得预签名 URL。是的,您无法通过 https 访问映射到 S3 存储桶 URL 的自定义域名。因为当您访问 https://example.com 并且 example.com 映射到 my-bucket-name.s3.amazonaws.com 时,S3 无法解密 SSL 流量。请参阅 this AWS 文档页面,限制部分。

无法在 Amazon S3 预签名 URL 中隐藏存储桶名称。这是因为正在向存储桶发出请求。签名只是授权请求。

一种方法是使用 Amazon CloudFront,将存储桶作为源。您可以将域名与 CloudFront 分配相关联,这与 CloudFront 获取其内容的来源无关。

Amazon CloudFront 支持预签名 URL。您可以通过 Origin Access Identity (OAI) 授予 CloudFront 对 S3 存储桶的访问权限,然后将分配配置为私有。然后,通过 CloudFront 预签名 URLs 访问内容。请注意,分配的全部内容都是私有的,因此您需要两个 CloudFront 分配(一个 public,一个私有),或者仅将 CloudFront 用于私有部分(并继续使用 direct-to-S3对于 public 部分)。

如果整个网站是私有的,那么您可以将 cookie 与 CloudFront 一起使用,而不必为每个 URL.

生成预签名的 URLs