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

CloudFront分发无法访问存储静态网站资源的S3桶

问题:CloudFront访问S3静态资源返回Access Denied错误

问题描述

部署托管静态资源的S3桶和对应的CloudFront分发后,访问分发始终返回包含access denied错误的纯CSV文件。按照AWS官方文档要求,未将桶配置为网站端点,而是使用OAC限制访问。控制台查看分发源时显示蓝色提示,但可复制的策略与桶权限中配置的策略一致。部署无报错,推测是配置细节错误,但排查一周仍未解决。

已确认信息

已验证桶与对象所有者一致:

> aws s3api list-buckets --query Owner.ID
"3fdbd1e5cad4dd2bbf4c66a3dbaded6b888fdb67ff6aa6e66203a4107fe17b72"
> aws s3api list-objects --bucket my-test-bucket --prefix index.html
{
    "Contents": [
        {
            "Key": "index.html",
            "LastModified": "2023-01-20T11:05:38+00:00",
            "ETag": "\"52f2df5ddf8c35391f3f15a7614def58\"",
            "Size": 325,
            "StorageClass": "STANDARD",
            "Owner": {
                "ID": "3fdbd1e5cad4dd2bbf4c66a3dbaded6b888fdb67ff6aa6e66203a4107fe17b72"
            }
        }
    ]
}

附CloudFormation模板

Resources:

  BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    DependsOn:
      - AppBucket
      - CloudFrontDistribution
    Properties:
      Bucket: !Ref AppBucket
      PolicyDocument:
        Id: MyPolicy
        Version: '2012-10-17'
        Statement:
          Sid: PolicyForCloudFrontPrivateContent
          Action: s3:GetObject
          Effect: Allow
          Principal:
            Service: cloudfront.amazonaws.com
          Condition:
            StringEquals:
              AWS:SourceArn: !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}
          Resource: !Sub arn:aws:s3:::${AppBucket}/*

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    DependsOn:
      - AppBucket
      - DefaultCachePolicy
      - DistributionOAC
    Properties:
      DistributionConfig:
        Enabled: true
        Origins:
          - Id: AppBucket
            DomainName: !GetAtt AppBucket.DomainName
            OriginPath: /*
            S3OriginConfig: {}
            OriginAccessControlId: !Ref DistributionOAC
        DefaultRootObject: index.html
        DefaultCacheBehavior:
          ViewerProtocolPolicy: redirect-to-https
          TargetOriginId: AppBucket
          CachePolicyId: !Ref DefaultCachePolicy

  DistributionOAC:
    Type: AWS::CloudFront::OriginAccessControl
    Properties: 
      OriginAccessControlConfig: 
          Name: ExampleOAC
          OriginAccessControlOriginType: s3
          SigningBehavior: always
          SigningProtocol: sigv4

  AppBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: 'test-spa-stack-bucket-app'
      PublicAccessBlockConfiguration:
        BlockPublicAcls : false
        BlockPublicPolicy : false
        IgnorePublicAcls : false
        RestrictPublicBuckets : false
              
  DefaultCachePolicy:
    Type: AWS::CloudFront::CachePolicy
    Properties: 
      CachePolicyConfig: 
        Name: test-cache-policy
        DefaultTTL: 10
        MaxTTL: 10
        MinTTL: 1
        ParametersInCacheKeyAndForwardedToOrigin: 
            CookiesConfig: 
              CookieBehavior: none
            EnableAcceptEncodingBrotli: true
            EnableAcceptEncodingGzip: true
            HeadersConfig: 
              HeaderBehavior: none
            QueryStringsConfig: 
              QueryStringBehavior: none

解决方案

1. 修复CloudFront OriginPath配置

模板中CloudFrontDistribution的OriginPath设为/*是核心错误。OriginPath用于指定CloudFront访问S3时的路径前缀,比如资源都在s3://bucket/path/下时才需要设置/path。设置/*会导致CloudFront请求的路径变成/*/index.html,而你的对象实际在桶根目录,因此找不到资源触发Access Denied。

修改方式:直接移除OriginPath配置,或设为空字符串:

Origins:
  - Id: AppBucket
    DomainName: !GetAtt AppBucket.DomainName
    # 移除 OriginPath: /* 这一行
    S3OriginConfig: {}
    OriginAccessControlId: !Ref DistributionOAC

2. 验证对象ACL(可选)

虽然已确认所有者一致,但需确保对象本身没有附加拒绝GetObject的ACL。执行以下命令检查:

aws s3api get-object-acl --bucket test-spa-stack-bucket-app --key index.html

确保所有者拥有FULL_CONTROL权限。

3. 清理CloudFront缓存

修改配置后,CloudFront可能仍缓存旧的错误响应,需手动创建缓存失效:

aws cloudfront create-invalidation --distribution-id <你的分发ID> --paths "/*"

4. 验证Bucket Policy的ARN匹配

确认Bucket Policy中的AWS:SourceArn与CloudFront分发ARN完全一致。执行以下命令获取分发ARN:

aws cloudfront get-distribution --id <分发ID> --query Distribution.Arn

对比Bucket Policy中的ARN是否完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:15:35