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

S3预签名URL上传文件返回403 Forbidden错误排查求助

问题排查与修复方案

1. 上传请求Body格式错误(核心原因)

生成预签名URL时指定的是put_object操作,该操作要求PUT请求直接上传原始文件内容,而非通过FormData包装。你的React代码用FormData.append('file', selectedFile)会在请求Body中添加multipart/form-data的边界信息,这和预签名时约定的ContentType(如image/jpeg)不匹配,导致S3签名验证失败,返回403。

修复后的React代码:

const uploadFile = async (signedUrl) => {
  try {
    const response = await fetch(signedUrl, {
      method: 'PUT',
      body: selectedFile, // 直接传入文件对象
      headers: {
        'Content-Type': selectedFile.type // 确保与预签名时的ContentType完全一致
      }
    });
    if (!response.ok) {
      throw new Error(`上传失败: ${response.statusText}`);
    }
    console.log('上传成功');
  } catch (error) {
    console.error('上传错误:', error);
  }
};

2. 桶策略中的占位符未替换

你提供的桶策略存在硬编码占位符,未替换为实际值,导致策略无法正确匹配IAM用户和存储桶:

  • Principal字段中的iamUsername需替换为实际创建的IAM用户名
  • Resource字段中的bucketName需替换为实际的S3存储桶名称

修正后的桶策略示例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678901:user/你的实际IAM用户名"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::你的实际桶名",
                "arn:aws:s3:::你的实际桶名/*"
            ]
        }
    ]
}

3. 冗余权限优化(可选)

你同时配置了IAM用户策略和桶策略,两者均授予s3:*权限。实际上只需其中一套配置即可,建议保留IAM用户策略(更符合权限最小化原则),可移除桶策略避免潜在的权限冲突。

额外验证步骤

  • 确认预签名URL生成时的ContentType与上传请求的Content-Type完全一致(包括大小写、参数等)
  • 验证IAM用户的访问密钥是否正确、未过期
  • 确认S3存储桶的「阻止公共访问」配置仅限制公共访问,不影响预签名URL的正常使用(该配置本身不干预预签名请求)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:06:33