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

使用AWS SAM/CloudFormation创建公共S3存储桶遇权限问题求助

解决方案:AWS SAM配置CloudFront托管的公共S3存储桶

一、修复BucketPolicy 403错误并替换弃用的AccessControl

添加公开BucketPolicy时出现403错误,核心原因是AWS默认开启了S3块公共访问(Block Public Access),阻止创建允许公共访问的策略。以下是替换弃用配置并解决403的完整模板:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: public-bucket-for-cloudfront

Parameters:
  BucketName:
    Description: S3 bucket name
    Type: String
    Default: 'my-test-public-bucket-abc123'

Resources:
  PublicBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: index.html
      CorsConfiguration:
        CorsRules:
          - AllowedOrigins:
              - "*"
            AllowedMethods:
              - GET
              - HEAD
            AllowedHeaders:
              - "*"
            MaxAge: 3000
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerPreferred
      # 关闭块公共访问限制,允许创建公开策略
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false

  PublicBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref PublicBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: PublicReadGetObject
            Effect: Allow
            Principal: "*"
            Action: "s3:GetObject"
            Resource: !Sub "arn:aws:s3:::${BucketName}/*"

关键调整点:

  • 移除了弃用的AccessControl: PublicRead
  • 添加PublicAccessBlockConfiguration,关闭所有阻止公共访问的选项,确保BucketPolicy能正常创建
  • 精简CORS规则:静态网站通常仅需GET/HEAD方法,移除不必要的POST/PUT/DELETE以降低安全风险

二、CloudFront托管的最佳实践(推荐)

直接公开S3桶存在安全隐患,推荐使用CloudFront Origin Access Identity(OAI),让CloudFront成为唯一能访问桶的实体,桶无需公开给所有人。这种方案既符合AWS安全规范,又能利用CloudFront的缓存、HTTPS、WAF等功能:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: cloudfront-s3-static-website

Parameters:
  BucketName:
    Description: S3 bucket name
    Type: String
    Default: 'my-test-cloudfront-bucket-abc123'
  DomainName:
    Description: Optional custom domain for CloudFront
    Type: String
    Default: ""

Resources:
  # S3存储桶(完全私有,仅允许CloudFront访问)
  StaticWebsiteBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: index.html
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerPreferred
      # 启用完整块公共访问,确保桶不被直接公开
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  # CloudFront Origin Access Identity
  CloudFrontOAI:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: OAI for static website bucket

  # 授权CloudFront OAI访问桶的策略
  BucketPolicyForCloudFront:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref StaticWebsiteBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: AllowCloudFrontAccess
            Effect: Allow
            Principal:
              AWS: !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOAI}"
            Action: "s3:GetObject"
            Resource: !Sub "arn:aws:s3:::${BucketName}/*"

  # CloudFront分发配置
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        DefaultRootObject: index.html
        Origins:
          - DomainName: !GetAtt StaticWebsiteBucket.RegionalDomainName
            Id: S3Origin
            S3OriginConfig:
              OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOAI}"
        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
          CachedMethods:
            - GET
            - HEAD
          ForwardedValues:
            QueryString: false
            Cookies:
              Forward: none
        # 若使用自定义域名,取消注释并配置ACM证书
        # Aliases:
        #   - !Ref DomainName
        # ViewerCertificate:
        #   AcmCertificateArn: !Ref CloudFrontCertificate
        #   SslSupportMethod: sni-only
        #   MinimumProtocolVersion: TLSv1.2_2021

核心优势:

  • 桶保持完全私有,避免直接公开带来的安全风险
  • 强制HTTPS访问,提升网站安全性
  • 利用CloudFront全球边缘节点加速内容分发
  • 无需调整块公共访问设置,从根源避免403错误

常见问题说明

  1. 为什么之前添加BucketPolicy会报403?
    AWS默认开启账号级别的S3块公共访问,阻止创建允许公共访问的策略。第一种方案通过显式关闭限制解决此问题,第二种方案使用OAI无需关闭限制。

  2. 什么时候用第一种方案?
    仅当你需要用户直接访问S3桶域名时才使用,否则优先选择CloudFront OAI方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:14:53