【问题标题】:403 Forbidden during POST to S3 bucketPOST 到 S3 存储桶期间禁止 403
【发布时间】:2017-11-12 01:04:33
【问题描述】:

我正在关注this tutorial,将一个简单的照片上传服务部署到 S3 存储桶。

我使用以下策略创建了一个新角色

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "s3:*"
         ],
         "Resource": [
            "arn:aws:s3:::BUCKET_NAME/*"
         ]
      }
   ]
}

授予所有授权AWS用户列表和bucket中的读/写访问权限,设置以下CORS

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

生成一个新的 Cognito 身份池并运行上面链接中的脚本。它运行成功,它打开了一个新相册,我可以在 S3 控制台中看到它,但是当我尝试将照片上传到相册时出现错误:

BUCKET_NAME.amazonaws.com/ALBUM_NAME//PHOTO_NAME.jpeg?uploads:1 POST https://BUCKET_NAME.amazonaws.com/ALBUM_NAME//PHOTO_NAME.jpeg?uploads 403 (Forbidden)

当我尝试访问脚本生成的链接时,我得到了这个 XML:

<Error>
<Code>InvalidRequest</Code>
<Message>
Key is not expected for the GET method ?uploads subresource
</Message>
<RequestId>******</RequestId>
<HostId>
******
</HostId>
</Error>

知道为什么会出现这个问题吗?

【问题讨论】:

  • 在您的错误消息中,我看到一个双斜杠:ALBUM_NAME//PHOTO_NAME.jpeg。我建议检查您在脚本中传递的参数是否有额外的斜杠,删除它并重试。
  • @Aditya 这是它在脚本中的显示方式,尽管我尝试将该行更改为 var albumPhotosKey = encodeURIComponent(albumName) + '/';它仍然存在。

标签: amazon-web-services amazon-s3 aws-sdk amazon-cognito amazon-iam


【解决方案1】:

您正在执行 HTTP POST,而不是 HTTP PUT。如果要传递密钥,则应该使用 PUT。如果你想做一个 POST,你需要按照page 中的描述在正文中传递密钥。

【讨论】:

    【解决方案2】:

    您缺少 s3 存储桶的部分权限。

    在此示例中,您希望授予 AWS 账户中的 IAM 用户访问您的存储桶之一(示例存储桶)的权限,并允许该用户添加、更新和删除对象。

    除了向用户授予 s3:PutObject、s3:GetObject 和 s3:DeleteObject 权限外,该策略还授予 s3:ListAllMyBuckets、s3:GetBucketLocation 和 s3:ListBucket 权限。这些是控制台所需的额外权限。有关向用户授予权限并使用控制台对其进行测试的示例演练,see An Example Walkthrough: Using user policies to control access to your bucket.

    {
       "Version":"2012-10-17",
       "Statement":[
          {
             "Effect":"Allow",
             "Action":[
                "s3:ListAllMyBuckets"
             ],
             "Resource":"arn:aws:s3:::*"
          },
          {
             "Effect":"Allow",
             "Action":[
                "s3:ListBucket",
                "s3:GetBucketLocation"
             ],
             "Resource":"arn:aws:s3:::examplebucket"
          },
          {
             "Effect":"Allow",
             "Action":[
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
             ],
             "Resource":"arn:aws:s3:::examplebucket/*"
          }
       ]
    }
    

    http://docs.aws.amazon.com/AmazonS3/latest/dev/example-policies-s3.html

    【讨论】:

    • 不幸的是,这并没有帮助,尽管有帮助的是从我上传的文件的参数中删除“ACL:'public-read'”。你能解释一下为什么这解决了这个问题吗?
    【解决方案3】:

    我也有同样的问题。而不是删除 ACL:'public-read' 我将其更改为 'public-read-write' 并且它起作用了。我只能假设,因为存储桶策略是读写,试图将其设置为只读会导致冲突......但只是猜测。

    【讨论】:

      【解决方案4】:

      这是旧的,但以防有人在使用 Cognito 上传时偶然发现它。

      就我而言,问题在于我的 S3 (us-east-1) 的区域与 Cognito 服务器区域 (eu-west-1) 不同。网上大部分例子只设置了一个区域,上传默认使用同一个区域。

      所以在 Javascript 中,要进行身份验证,您需要设置 Cognito 区域:

      AWS.config.region = 'eu-west-1'; // Cognito Region
      AWS.config.credentials = new AWS.CognitoIdentityCredentials({
          IdentityPoolId: 'eu-west-1:51a4f410-7694-4222-89b5-...',
      });
      

      然后在上传之前设置您的 S3 存储桶区域:

      var s3 = new AWS.S3({
        region: 'us-east-1', //Bucket region
        apiVersion: '2006-03-01',
        params: {Bucket: [BUCKET-NAME]}
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-12
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        • 2014-12-21
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多