无法将自定义标头添加到 CloudFront 分发 - 使用 s3 作为后端

无法将自定义标头添加到 CloudFront 分发 - 使用 s3 作为后端

我们正在尝试将一些自定义标头放入我们的云源分布中,但它没有按预期工作。以下是场景。

我们有一个名为“example-images”的 s3 存储桶,其中包含所有静态内容,s3 存储桶可供公众访问。具有以下 CORS 策略

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <ExposeHeader>Access-Control-Allow-Credentials</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

我们可以使用 curl 根据示例输出通过 URL 访问 s3 内容。

x-amz-id-2: xxxxxxxxxxxx
x-amz-request-id: xxxxxxxxxxxx
Date: Wed, 05 Oct 2016 04:10:26 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Expose-Headers: Access-Control-Allow-Credentials
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Last-Modified: Mon, 26 Sep 2016 13:12:58 GMT
ETag: "xxxxxxxxxxxxxx"
Accept-Ranges: bytes
Content-Type: image/png
Content-Length: 1630
Server: AmazonS3

然后我们创建了一个云端分布来提供这些内容。

根据文档,我们在“默认来源”中设置了以下值

  • 限制存储桶访问 = 否
  • 原始自定义标题 一些自定义标题

    例如“访问控制允许凭据 = true”

在 CF 分布“行为”中我们有以下设置。

  • 协议策略 = http & https
  • 允许 http 方法 = GET、HEAD、OPTIONS。
  • 转发标头 = 白名单
  • 白名单标头 = 来源
  • 对象缓存 = 使用原始缓存标头

使用 CF Distribution URL 时我们仍然无法查看自定义标头。

curl -sI -H "Origin: example.com" -H "Access-Control-Request-Method: GET" -H "Access-Control-Allow-Credentials: GET"
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 1630
Connection: keep-alive
Date: Wed, 05 Oct 2016 04:03:20 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Expose-Headers: Access-Control-Allow-Credentials
Last-Modified: Mon, 26 Sep 2016 13:12:58 GMT
ETag: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin
Age: 1231
X-Cache: Hit from cloudfront
Via: 1.1 xxxxxxxx.cloudfront.net (CloudFront)
X-Amz-Cf-Id: xxxxxxxxxxxxxxxxxxxxx

您能帮助我们找出这里缺少什么设置吗?

答案1

您可以使用以下方式向 CloudFront/S3 的响应添加自定义标头:Lambda@Edge函数。lambda 代码在本地边缘位置内运行,但需要在us-east-1区域中创建和维护。

这里的示例代码使用 nodeJS 6.10 添加x-frame-options响应标头,但你可以添加任何不是受限制的由 AWS 提供。

'use strict'; 
 exports.handler = (event, context, callback) => {
   const response = event.Records[0].cf.response; 
   const headers = response.headers; 
   response.headers['x-frame-options'] = [{"key":"X-Frame-Options","value":"SAMEORIGIN"}]; 
   console.log(response.headers); 
   callback(null, response);
 }; 

创建 Lambda 的最终版本,然后将 Lambda 版本的触发器配置设置为origin-response路径模式行为的 CloudFront 事件类型。

示例代码将事件记录到 CloudWatch 日志服务中以供调试。如果您还没有,则需要设置一个 lambda 执行 IAM 角色,该角色允许允许 CloudWatch 日志操作由edgelambda.amazonaws.com和承担的策略lambda.amazonaws.com

允许将日志写入 CloudWatch 的基本 Lambda 执行策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*",
            "Effect": "Allow"
        }
    ]
}

信任关系允许 Lambda 和 Lambda@Edge 承担角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "edgelambda.amazonaws.com",
          "lambda.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

如果 AWS 只是允许使用 CloudFront GUI 设置自定义标头,那就更好了,但在此之前,该解决方案应该可以满足您的要求。

答案2

我刚刚在查看器响应中实现了标头操作。它只是向 CloudFront 发送的响应添加标头。

您需要使用名为“CloudFront Function”的新工具。 https://console.aws.amazon.com/cloudfront/v3/home#/functions/ 直接在CDN的218+PoP上运行,而不只是在区域PoP上运行,函数需要用JS编写。

以下是 AWS 博客文章,比较了 lambda@edge 和 CloudFront 函数:https://aws.amazon.com/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/

从 AWS 博客文章来看,最常见的用例是:

  • HTTP 标头操作
  • 缓存键操作和规范化
  • URL 重写和重定向
  • 访问授权

我的功能很简单:

    function handler(event) {
      var response = event.response;
      var headers = response.headers;

      // Set custom header
      headers['custom-header'] = {value: '*'}; 

      // Return the response to viewers 
      return response;
    }

您所要做的只是将其附加到您的发行版,它就可以工作了。

相关内容