【问题标题】:Amazon S3 bucket returning 403 ForbiddenAmazon S3 存储桶返回 403 Forbidden
【发布时间】:2022-01-22 10:10:18
【问题描述】:

我最近继承了一个使用 S3 存储资产的 Rails 应用程序。我已将所有资产转移到我的 S3 存储桶中,没有任何问题。但是,当我将应用程序更改为指向新存储桶时,我得到 403 Forbidden Status。

我的 S3 存储桶设置了以下设置:

权限

每个人都可以列出

存储桶政策

{
 "Version": "2012-10-17",
 "Statement": [
    {
        "Sid": "PublicReadGetObject",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::bucketname/*"
    }
 ]
}

CORS 配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://www.appdomain.com</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

静态虚拟主机

已启用。

我还能做些什么来让公众接触到这些资产?

【问题讨论】:

    标签: amazon-web-services amazon-s3


    【解决方案1】:

    我知道这是一个旧线程,但我刚刚遇到了同样的问题。我让一切工作了几个月,但它突然停止工作,给我一个403 Forbidden 错误。事实证明,系统时钟才是真正的罪魁祸首。我认为 s3 使用某种基于时间的令牌,其寿命很短。就我而言,我只是跑了:

    ntpdate pool.ntp.org
    

    问题就消失了。如果有任何相关性,我正在运行CentOS 6。这是示例输出:

    19 Aug 20:57:15 ntpdate[63275]: step time server ip_address offset 438.080758 sec
    

    希望有帮助!

    【讨论】:

    • 感谢发布。我刚才在 Windows 上遇到了同样的问题。修正系统时间解决了。
    • 上帝保佑你,好人。请不要犹豫,回答旧问题。
    • 这是我的问题。不知何故,我的 docker 容器中的时钟漂移了,这不是一个明显的诊断!
    • 我正在使用虚拟机快照并撕毁我的头发。我想为这个答案投票十次。
    • 更正了时间。即使有 0.1 秒的偏差,s3 也会返回 403 禁止错误。
    【解决方案2】:

    也可能是需要根据AWS docs设置合适的策略。

    为有问题的存储桶提供此政策:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "PublicReadGetObject",
          "Effect": "Allow",
          "Principal": "*",
          "Action": [
            "s3:GetObject"
          ],
          "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
        }
      ]
    }
    

    【讨论】:

    • 我必须添加一个从资源中删除“/*”的语句。
    • 如果我从资源字符串的末尾删除/*,策略编辑器会返回Action does not apply to any resources
    【解决方案3】:

    问题是转移是根据this thread 完成的,这本身不是问题。问题来自之前的开发人员在传输之前没有更改文件的权限。这意味着我无法管理任何文件,即使它们在我的存储桶中。

    通过从以前的存储桶中干净地重新下载文件、删除旧的幻像文件、重新上传新文件并设置其权限以允许公开读取文件来解决问题。

    【讨论】:

    • 由于这是公认的答案,我只想补充一点,AWS s3 同步不会传输每个对象的 ACL 设置。有可能使用 ACL 列表将对象单独设置为公共。这个项目github.com/cobbzilla/s3s3mirror 提供了-C 选项,我没能成功。作为最后的手段,您可以为存储桶中的每个文件夹设置存储桶策略,允许 Principal: * 到 GetObjects。
    【解决方案4】:

    我有同样的问题,只是在策略桶资源的末尾添加 * 解决了它

    {
      "Version":"2012-10-17",
      "Statement":[{
        "Sid":"PublicReadGetObject",
            "Effect":"Allow",
          "Principal": "*",
          "Action":["s3:GetObject"],
          "Resource":["arn:aws:s3:::example-bucket/*"
          ]
        }
      ]
    }
    

    【讨论】:

    • 为什么会被否决?在我的资源末尾添加 /* 解决了这个问题。
    • 我不知道哪些人已经否决了它的实际答案
    • @user3470929 我没有投反对票,但因为原始问题已经使用了/* - 或者至少他们已经编辑以在问题中反映这一点。
    【解决方案5】:

    这是我用来使我的 S3 存储桶中的 index.html 文件可从互联网访问的存储桶策略:

    我还需要转到权限 -> “阻止公共访问”并删除存储桶的阻止公共访问规则。像这样:

    还要确保每个存储桶中各个对象的访问权限对公众开放。在这里检查:

    【讨论】:

    • 公开按钮是我所缺少的!
    • 编辑 - 我的错误是我忘记使用正确的 aws 配置文件:(
    【解决方案6】:

    在设置正确的权限后为我解决了这个问题的一个奇怪的事情是我从文件名中删除了扩展名。所以我在存储桶中有很多项目都具有相同的权限,有些找到了,有些返回了 403。唯一的区别是那些没有工作的项目在文件名的末尾有.png。当我删除他们工作正常。不知道为什么。

    【讨论】:

      【解决方案7】:

      这里的另一个“解决方案”:我使用 Buddy 自动将 github 存储库上传到 s3 存储桶,这需要对存储桶进行编程写入访问。 IAM 用户的访问策略首先如下所示:(仅允许在目标存储桶中执行这 6 个操作)。

          {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "VisualEditor0",
                  "Effect": "Allow",
                  "Action": [
                      "s3:PutObject",
                      "s3:GetObject",
                      "s3:ListAllMyBuckets",
                      "s3:ListBucket",
                      "s3:DeleteObject",
                      "s3:PutObjectAcl"
                  ],
                  "Resource": ""arn:aws:s3:::<bucket_name>/*"
              }
          ]
      }
      

      我的存储桶访问策略如下:(允许 IAM 用户进行读/写访问)。

      {
      "Version": "2012-10-17",
      "Id": "1234",
      "Statement": [
          {
              "Sid": "5678",
              "Effect": "Allow",
              "Principal": {
                  "AWS": "arn:aws:iam::<IAM_user_arn>"
              },
              "Action": [
                  "s3:DeleteObject",
                  "s3:GetObject",
                  "s3:GetObjectAcl",
                  "s3:PutObject"
              ],
              "Resource": "arn:aws:s3:::<bucket_name>/*"
          }
      

      但是,这一直给我 403 错误。

      我的解决方案是让 IAM 用户访问所有 s3 资源:

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "VisualEditor0",
                  "Effect": "Allow",
                  "Action": [
                      "s3:PutObject",
                      "s3:GetObject",
                      "s3:ListAllMyBuckets",
                      "s3:ListBucket",
                      "s3:DeleteObject",
                      "s3:PutObjectAcl"
                  ],
                  "Resource": "*"
              }
          ]
      }
      

      这让我绕过了 403 错误,但显然它听起来不像它应该的样子。

      【讨论】:

        【解决方案8】:

        对我来说,其他答案都不起作用。文件权限、存储桶策略和时钟都很好。对我来说,这个问题是断断续续的,虽然听起来可能很陈词滥调,但以下两种方法以前都对我有用:

        1. 退出并重新登录。
        2. 如果您尝试上传单个文件,请尝试进行批量上传。相反,如果尝试上传单个文件,请尝试进行批量上传。

        【讨论】:

          【解决方案9】:

          刚刚在我的 iPhone 应用中发现了同样的问题。它在具有相同配置和 S3 设置的 Android 上运行良好,但 iPhone 应用程序抛出错误。在检查了他们的日志后,我就这个问题联系了亚马逊支持团队;他们告诉我你的 iPhone 有日期和时间。然后我去了我的 iPhone 的设置并调整了正确的日期和时间。然后我尝试上传新图片,它按预期工作。

          如果您遇到同样的问题并且您的 iPhone 或模拟器中的日期或时间错误;这可能会对你有所帮助。

          谢谢!

          【讨论】:

            【解决方案10】:

            对我来说,它是访问控制标签下的公共访问

            只要保证公共访问下的读写权限为Yes,默认为-,即

            编码愉快。

            JFYI:我正在使用 Flutter 进行 Android 开发。

            【讨论】:

              【解决方案11】:

              确保您使用正确的 AWS 配置文件!!!! (开发\产品等...)

              【讨论】:

                【解决方案12】:

                尝试使用 Python 中预签名的 URL 从 JavaScript 将文件放入 S3 时遇到此错误。原来我的 Python 需要 ContentType 属性。

                添加后,以下内容就起作用了:

                import boto3
                import requests
                
                access_key_id = 'AKIA....'
                secret_access_key = 'LfNHsQ....'
                bucket = 'images-dev'
                filename = 'pretty.png'
                
                s3_client = boto3.client(
                  's3',
                  aws_access_key_id=access_key_id,
                  aws_secret_access_key=secret_access_key
                )
                
                # sign url
                response = s3_client.generate_presigned_url(
                  ClientMethod = 'put_object',
                  Params = {
                    'Bucket': bucket,
                    'Key': filename,
                    'ContentType': 'image/png',
                  }
                )
                
                print(" * GOT URL", response)
                
                # NB: to run the PUT command in Python, one must remove the ContentType attr above!
                # r = requests.put(response, data=open(filename, 'rb'))
                # print(r.status_code)
                

                然后可以使用来自客户端的 url 将该图像放入 S3:

                var xhr = new XMLHttpRequest();
                xhr.open('PUT', url);
                xhr.onreadystatechange = () => {
                  if (xhr.readyState === 4) {
                    if (xhr.status !== 200) {
                      console.log('Could not upload file.');
                    }
                  }
                };
                
                xhr.send(file);
                

                【讨论】:

                  猜你喜欢
                  • 2014-01-28
                  • 2015-08-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-09-16
                  • 2020-08-12
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多