6

我有一个不完全正统的 CF->S3 设置。这里的相关组件是:

  1. Cloudfront 分发与origin s3.ap-southeast-2.amazonaws.com

  2. 添加 S3 授权(版本 2)查询字符串(使用函数使用的 S3 策略签名)的 Lambda@Edge 函数(原始请求)。

Lambda 返回的请求是完全正确的。如果我记录 uri、主机和查询字符串,我会得到我请求的文件。但是,如果我直接通过 Cloudfront 链接访问它,请求将失败,因为它不再使用AWSAccessKeyID,而是选择使用x-amz-cf-id(但使用相同的签名、Amz-Security-Token 等)。更正:它可能不会替代,但需要补充。

我知道是这种情况,因为我已经退回了 StringToSignSignatureProvided。这些都与 Lambda 响应匹配,除了AWSAccessKeyID已替换为x-amz-cf-id.

这显然是一个非常具体的问题。我可能不得不考虑改造这个架构,但我不希望这样做。有几个要求导致我放弃了这种不完全常规的设置。

4

3 回答 3

1

我相信AWSAccessKeyID=>x-amz-cf-id替换是两种机制的结果:

首先,您需要配置 CloudFront 以将查询参数转发到源。没有它,它将剥离所有参数。如果您使用 S3 签名的 URL,请确保还根据所有参数进行缓存,否则您最终将没有任何访问控制。

其次,CloudFront 将 附加到不发送到 S3 源x-amz-cf-id的请求。您可以在 CloudFront 控制台上仔细检查源类型,并且您需要确保它被报告为 S3。我有一篇博客文章详细描述了它。

但是使用 Lambda@Edge 将 S3 签名添加到所有请求中会破坏目的。如果您想让存储桶保持私有并且只允许 CloudFront 访问它,那么请使用原始访问身份,这正是用例的需要。

于 2019-08-07T09:18:49.893 回答
0

因此,对于 Authentication V2 或 V4,x-amz-cf-id附加到源请求且 Lambda@Edge 源请求函数无法访问的标头必须包含在身份验证字符串中。这是不可能的。

简单的解决方案是使用 Cloudflare 中的内置 S3 集成,如果像我一样使用 Lambda@Edge 源请求函数来切换存储桶,这是您想要的目标。对于您要使用的每个存储桶,添加以下策略以允许您的 CF 分配访问存储桶中的对象。

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <CloudfrontID>"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*"
        }
    ]
}

CloudfrontID指的是Origin Access Identity下的ID,而不是Amazon S3 Canonical ID

于 2018-03-08T03:59:05.610 回答
0

X-amz-cf-id 是 CF 的保留标头,它可以通过事件作为 event['Records'][0]['cf']['config']['requestId'] 获取。您不必使用 X-amz-cf-id 计算 Authentication V4。

于 2020-04-23T06:36:09.520 回答