You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda@Edge多区域S3访问报错AuthorizationHeaderMalformed求助

问题:CloudFront Lambda@Edge路由到us-east-1 S3存储桶时授权头错误

我有两个S3存储桶,分别部署在eu-west-1和us-east-1区域,通过Lambda@Edge在源请求阶段实现动态路由:根据Lambda执行的边缘区域,将请求转发到对应区域的S3存储桶。对应区域的服务器通过curl请求同路径文件(文件内容为区域标识)时,eu-west-1区域的请求正常,但us-east-1区域的请求失败,报错如下:

$ curl -L cdn.mywebsite.cloud/welcome.html
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AuthorizationHeaderMalformed</Code><Message>The authorization header is malformed; the region 'eu-west-1' is wrong; expecting 'us-east-1'</Message><Region>us-east-1</Region><RequestId>N93PW0DBYKD9J801</RequestId><HostId>PVi9MrrxoPmWMIV48Ao/eNogihE/TFFAGvPjkwvRfBZPHLl4Myys5SQ/3vxY1WYuLXmIBt5dJGE=</HostId></Error>

Lambda@Edge逻辑代码如下:

us_bucket = "cdn-origin-bucket-us-east-1-XXXX.s3.us-east-1.amazonaws.com"
eu_bucket = "cdn-origin-bucket-eu-west-1-XXXX.s3.eu-west-1.amazonaws.com"
# ap_bucket = "mybucket-ap.amazonaws.com"
default_bucket = "cdn-origin-bucket-us-east-1-XXXX.s3.us-east-1.amazonaws.com"

# Regions Mapping
regions_mapping = {
  # NA
  "us-east-1": us_bucket,
  "us-east-2": us_bucket,
  "us-west-1": us_bucket,
  "us-west-2": us_bucket,
  "ca-central-1": us_bucket,
  # EU
  "eu-central-1": eu_bucket,
  "eu-central-1": eu_bucket,  # 存在重复键,属于代码冗余
  "eu-west-1": eu_bucket,
  "eu-west-2": eu_bucket,
  "eu-west-3": eu_bucket,
  "eu-north-1": eu_bucket,
}

def lambda_handler(event, context):
  request = event['Records'][0]['cf']['request']

  # Identify edge region
  lambda_region = context.invoked_function_arn.split(':')[3]

  # Get S3 bucket based on regions mapping
  domain_name = regions_mapping.get(lambda_region, default_bucket)

  # Update origin request object
  request['origin']['s3']['domainName'] = domain_name
  request['origin']['s3']['region'] = lambda_region
  request['headers']['host'] = [{'key': 'host', 'value': domain_name}]

  return request

我已参考AWS官方多区域Active-Active架构指南,但问题仍未解决,希望能排查原因,可提供更多配置细节。


问题根源

报错显示授权头使用了错误的区域(eu-west-1),但请求的是us-east-1的存储桶。核心原因是:CloudFront会预先为原始配置的S3存储桶生成签名授权头,当你在Lambda@Edge中动态切换到不同区域的S3存储桶时,原有授权头的区域信息与目标存储桶不匹配,导致S3拒绝请求。

另外代码中regions_mapping重复定义了"eu-central-1": eu_bucket,虽不影响当前问题,但建议清理冗余代码。

解决步骤

  1. 禁用CloudFront自动签名:
    当使用Lambda@Edge动态路由多区域S3存储桶时,不能依赖CloudFront自动生成的S3授权头。需将CloudFront的源配置改为自定义源(而非默认的S3源类型),这样CloudFront不会自动添加授权头;若内容允许公开访问,也可直接设置S3存储桶为公有读权限。

    若需私有访问,需在Lambda@Edge中使用IAM角色生成目标存储桶的签名授权头(注意Lambda@Edge角色需具备跨区域S3访问权限)。

  2. 修正Lambda代码的区域设置:
    当前代码中request['origin']['s3']['region']使用的是Lambda执行的边缘区域,但正确的做法是使用目标存储桶所在的区域(而非边缘区域)。修改代码如下:

    us_bucket = "cdn-origin-bucket-us-east-1-XXXX.s3.us-east-1.amazonaws.com"
    eu_bucket = "cdn-origin-bucket-eu-west-1-XXXX.s3.eu-west-1.amazonaws.com"
    default_bucket = "cdn-origin-bucket-us-east-1-XXXX.s3.us-east-1.amazonaws.com"
    
    # 存储桶与对应区域的映射
    bucket_region_mapping = {
        us_bucket: "us-east-1",
        eu_bucket: "eu-west-1"
    }
    
    regions_mapping = {
      # NA
      "us-east-1": us_bucket,
      "us-east-2": us_bucket,
      "us-west-1": us_bucket,
      "us-west-2": us_bucket,
      "ca-central-1": us_bucket,
      # EU
      "eu-central-1": eu_bucket,
      "eu-west-1": eu_bucket,
      "eu-west-2": eu_bucket,
      "eu-west-3": eu_bucket,
      "eu-north-1": eu_bucket,
    }
    
    def lambda_handler(event, context):
      request = event['Records'][0]['cf']['request']
      lambda_region = context.invoked_function_arn.split(':')[3]
      domain_name = regions_mapping.get(lambda_region, default_bucket)
      
      # 获取目标存储桶对应的正确区域
      target_region = bucket_region_mapping.get(domain_name, "us-east-1")
      
      request['origin']['s3']['domainName'] = domain_name
      request['origin']['s3']['region'] = target_region
      request['headers']['host'] = [{'key': 'host', 'value': domain_name}]
    
      return request
    
  3. 清除CloudFront缓存:
    修改Lambda代码和CloudFront配置后,需手动清除CloudFront缓存,确保新配置生效。

额外检查点

  • 确认存储桶权限:若使用自定义源,需确保存储桶允许CloudFront IP范围访问,或Lambda角色具备目标存储桶的访问权限。
  • 确认Lambda@Edge角色权限:需允许Lambda访问CloudFront请求上下文,以及跨区域S3存储桶的访问权限。

内容的提问来源于stack exchange,提问作者foroozf001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:12:52