You need to enable JavaScript to run this app. AWS S3预签名URL下载文件返回Access Denied错误排查求助
优惠活动
大模型
产品
解决方案
定价
更多

AWS S3预签名URL下载文件返回Access Denied错误排查求助

1. 首先排除@字符URL编码的影响

URL自动将@转义为%40是HTTP标准行为,S3可以正常识别编码后的路径,这个不是导致Access Denied的原因,可以直接排除。

2. 先修正IAM权限配置的错误

你当前的serverless.yml里的IAM配置存在两处可优化/错误点:

  • 权限动作s3:ListObject拼写错误,正确的列桶对象动作是s3:ListBucket,如果你没有列桶的需求可以直接删掉这个无效动作
  • 不建议配置"arn:aws:s3:::*"这种全桶资源权限,风险很高,直接保留你自己的存储桶ARN即可,修正后的权限示例:
iam:
  role:
    statements:
      - Effect: 'Allow'
        Action:
          - 's3:GetObject'
          - 's3:PutObject'
          - 's3:CreateBucket'
        Resource:
          - "arn:aws:s3:::my_bucket/*"
          - "arn:aws:s3:::my_bucket"

如果需要列桶权限,单独加一条statement,因为ListBucket的作用资源是桶本身,不能作用到对象路径:

- Effect: 'Allow'
  Action: 's3:ListBucket'
  Resource: "arn:aws:s3:::my_bucket"

3. 排查其他常见导致Access Denied的原因

  • KMS加密权限缺失:如果你的S3桶开启了默认KMS加密,或者目标文件是用KMS密钥加密的,需要给Lambda执行角色添加对应KMS密钥的kms:Decrypt权限,否则即使有S3 GetObject权限也会报拒绝访问。
  • 区域不匹配:生成预签名URL的boto3客户端的区域要和S3桶实际所在区域完全一致,如果你的Lambda部署区域和桶的区域不同,需要在初始化s3客户端时显式指定区域:
s3 = boto3.client('s3', region_name='你的桶所在区域,比如ap-southeast-1')
  • URL过期:generate_presigned_url默认的过期时间是3600秒(1小时),如果超过这个时间再访问就会报错,你可以通过ExpiresIn参数自定义过期时长,最长不超过7天(使用IAM角色签名的情况下)。
  • 对象所有权问题:如果目标文件是由其他AWS账号、或者其他身份上传的,没有给你的Lambda执行角色开放读取权限,也会出现拒绝访问,可以检查文件的ACL配置。
  • 桶策略限制:检查S3桶本身的桶策略,是否有规则拦截了Lambda角色的访问请求,或者开启了公共访问阻止的相关规则。

内容的提问来源于stack exchange,提问作者J. Doe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 17:03:04