绕过 cloudfront 中 S3 身份验证中包含 x-amz-cf-id 标头的需要

dan*_*mly 6 amazon-s3 amazon-web-services amazon-cloudfront aws-lambda-edge

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

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

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

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

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

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

dan*_*mly 0

因此,对于身份验证 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>/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

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