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

基于Serverless Framework创建公开S3存储桶遇权限问题求助

解决Serverless Framework创建S3存储桶的权限问题

问题背景

需创建满足以下需求的S3存储桶:

  • 存放公开资产,支持通过对象URL直接在互联网分享
  • 仅允许API Gateway触发的Lambda函数执行写入操作
  • 禁止其他途径(如控制台)的写入访问

现有模板存在两个问题:

  • 通过AWS SDK(Lambda中调用)上传文件时提示权限拒绝
  • 控制台上传的文件无法通过URL公开访问

现有模板的核心问题

  1. 缺少Lambda写入权限:当前Bucket Policy仅允许公开读取对象,未授权Lambda执行角色的写入操作(如s3:PutObject、s3:PutObjectAcl)
  2. 对象公开访问未完全生效:控制台上传的对象默认ACL可能不是public-read,且Bucket级别的AccessControl: PublicRead在现代S3配置中优先级较低,需通过Bucket Policy明确强制对象的公开读取权限
  3. SecureTransport策略范围不全:当前仅拒绝对象级别的非HTTPS操作,未覆盖Bucket级别的操作,可能导致部分写入请求被误拦截

修正后的完整模板

# S3存储桶资源
LogoPublicS3Bucket: 
  Type: "AWS::S3::Bucket" 
  Properties: 
    BucketName: portal-settings-${self:custom.stage}-public-bucket
    CorsConfiguration: 
      CorsRules: 
        - AllowedMethods: 
            - GET 
            - HEAD 
          AllowedOrigins: 
            - "*"
          AllowedHeaders:
            - "*"
    VersioningConfiguration: 
      Status: Enabled
    # 配置公开访问控制,确保Bucket Policy可生效
    PublicAccessBlockConfiguration:
      BlockPublicAcls: false
      BlockPublicPolicy: false
      IgnorePublicAcls: false
      RestrictPublicBuckets: false

# 主Bucket Policy:控制公开读取和Lambda写入
LogoPublicS3BucketPolicy: 
  Type: 'AWS::S3::BucketPolicy' 
  Properties: 
    Bucket: 
      Ref: LogoPublicS3Bucket
    PolicyDocument: 
      Statement:
        # 允许所有用户通过HTTPS读取对象
        - Sid: PublicReadForGetBucketObjects
          Effect: Allow
          Principal: '*'
          Action: 's3:GetObject'
          Resource: !Join ['', ['arn:aws:s3:::', !Ref LogoPublicS3Bucket, '/*']]
          Condition:
            Bool:
              'aws:SecureTransport': true
        # 仅允许Lambda执行角色执行写入操作(替换为你的Lambda角色ARN)
        - Sid: AllowLambdaWriteAccess
          Effect: Allow
          Principal:
            AWS: !GetAtt YourLambdaExecutionRole.Arn
          Action:
            - 's3:PutObject'
            - 's3:PutObjectAcl'
          Resource: !Join ['', ['arn:aws:s3:::', !Ref LogoPublicS3Bucket, '/*']]
          Condition:
            Bool:
              'aws:SecureTransport': true

# 强制HTTPS访问策略(覆盖Bucket和对象)
LogoPublicS3SecureTransportPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket:
      Ref: LogoPublicS3Bucket
    PolicyDocument:
      Statement:
        - Effect: "Deny"
          Action: "s3:*"
          Principal: '*'
          Resource:
            - !Join ['', ['arn:aws:s3:::', !Ref LogoPublicS3Bucket]]
            - !Join ['', ['arn:aws:s3:::', !Ref LogoPublicS3Bucket, '/*']]
          Condition:
            Bool:
              'aws:SecureTransport': false

关键修正说明

  1. 配置PublicAccessBlock:明确禁用公开访问限制,确保Bucket Policy能正常生效
  2. 添加Lambda写入权限:通过Principal指定Lambda执行角色的ARN,授权必要的写入操作,确保Lambda能上传并设置对象为公开可读
  3. 完善公开读取策略:给公开读取操作加上aws:SecureTransport条件,确保仅HTTPS访问
  4. 扩展SecureTransport策略范围:同时拒绝Bucket和对象级别的非HTTPS操作,避免权限遗漏
  5. 移除旧的AccessControl:现代S3推荐用Bucket Policy替代Bucket级别的AccessControl配置

Lambda角色补充配置

需在Lambda的执行角色中添加S3权限(可通过Serverless Framework的iamRoleStatements配置):

provider:
  name: aws
  iamRoleStatements:
    - Effect: Allow
      Action:
        - s3:PutObject
        - s3:PutObjectAcl
      Resource: !Join ['', ['arn:aws:s3:::', !Ref LogoPublicS3Bucket, '/*']]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:47:06