基于Serverless Framework创建公开S3存储桶遇权限问题求助
解决Serverless Framework创建S3存储桶的权限问题
问题背景
需创建满足以下需求的S3存储桶:
- 存放公开资产,支持通过对象URL直接在互联网分享
- 仅允许API Gateway触发的Lambda函数执行写入操作
- 禁止其他途径(如控制台)的写入访问
现有模板存在两个问题:
- 通过AWS SDK(Lambda中调用)上传文件时提示权限拒绝
- 控制台上传的文件无法通过URL公开访问
现有模板的核心问题
- 缺少Lambda写入权限:当前Bucket Policy仅允许公开读取对象,未授权Lambda执行角色的写入操作(如
s3:PutObject、s3:PutObjectAcl) - 对象公开访问未完全生效:控制台上传的对象默认ACL可能不是
public-read,且Bucket级别的AccessControl: PublicRead在现代S3配置中优先级较低,需通过Bucket Policy明确强制对象的公开读取权限 - 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
关键修正说明
- 配置PublicAccessBlock:明确禁用公开访问限制,确保Bucket Policy能正常生效
- 添加Lambda写入权限:通过
Principal指定Lambda执行角色的ARN,授权必要的写入操作,确保Lambda能上传并设置对象为公开可读 - 完善公开读取策略:给公开读取操作加上
aws:SecureTransport条件,确保仅HTTPS访问 - 扩展SecureTransport策略范围:同时拒绝Bucket和对象级别的非HTTPS操作,避免权限遗漏
- 移除旧的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
相关产品推荐
相关产品推荐

