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
相关产品推荐
相关产品推荐

