使用Node.js对s3 bucket进行api调用时拒绝访问

使用Node.js对s3 bucket进行api调用时拒绝访问,node.js,amazon-web-services,amazon-s3,Node.js,Amazon Web Services,Amazon S3,使用Node.js,我正在制作一个api,用于在AWS上调用我的s3存储桶。当我尝试使用putObject方法时,我收到以下错误: message: 'Access Denied', code: 'AccessDenied', region: null, time: 2018-07-27T17:08:29.555Z, ... etc } 我在C:/User/{User}/.aws/目录中有一个配置和凭证文件 配置文件: [default] region=us-east-2

使用Node.js,我正在制作一个api,用于在AWS上调用我的s3存储桶。当我尝试使用
putObject
方法时,我收到以下错误:

  message: 'Access Denied',
  code: 'AccessDenied',
  region: null,
  time: 2018-07-27T17:08:29.555Z,
  ... etc
} 我在
C:/User/{User}/.aws/
目录中有一个配置和凭证文件

配置文件:

[default]
region=us-east-2
output=json
凭据文件:

[default]
aws_access_key_id=xxxxxxxxxxxxxxx
aws_secret_access_key=xxxxxxxxxxx
我为IAM用户和Bucket创建了策略。以下是我的IAM用户内联策略:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListAllMyBuckets",
                    "s3:PutObject",
                    "s3:GetObject"
                ],
                "Resource": [
                    "arn:aws:s3:::*"
                ]
            }
        ]
    }
我的桶政策是:

{
    "Version": "2012-10-17",
    "Id": "Policy1488494182833",
    "Statement": [
        {
            "Sid": "Stmt1488493308547",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::134100338998:user/Test-User"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*"
            ],
            "Resource": "arn:aws:s3:::admin-blog-assets"
        }
    ]
}
最后是我的api

var fs = require('fs'),
    AWS = require('aws-sdk'),
    s3 = new AWS.S3('admin-blog-assets');

...

  var params = {
  Bucket: 'admin-blog-assets',
  Key: file.filename,
  Body: fileData,
  ACL:'public-read'
  };
  s3.putObject(params, function (perr, pres) {
      if (perr) {
          console.log("Error uploading image: ", perr);                                                
      } else {
          console.log("uploading image successfully");                       
      }                      
  });

我已经为此绞尽脑汁好几个小时了,有人能帮忙吗?

我相信问题的根源与您如何定义
s3
对象有关,如
s3=new AWS.s3('admin-blog-assets')

如果你看这个例子,它有这样一行:

var bucketPromise = new AWS.S3({apiVersion: '2006-03-01'}).createBucket({Bucket: bucketName}).promise();
其中,传递给AWS.S3的参数是一个包含该
apiVersion
字段的对象。但是您正在传递一个字符串值

概述部分提供了更多信息:

使用s3var S3=new AWS.S3()发送请求; s3.abortMultipartUpload(参数,函数(错误,数据){if(错误) console.log(err,err.stack);//否则发生错误
console.log(数据);//成功响应});锁定 API版本,以确保S3对象使用此特定 API,则可以通过将apiVersion选项传递给 建造商:

var s3 = new AWS.S3({apiVersion: '2006-03-01'}); You can also set the
使用s3服务在AWS.config.apiVersions中全局设置API版本 标识符:

AWS.config.apiVersions={s3:'2006-03-01',//其他服务API 版本}

var s3 = new AWS.S3();

您授予的一些权限是bucket权限,而其他权限是object权限。有匹配
s3:Get*
s3:Put*
的操作同时应用于bucket和对象

“资源”:“arn:aws:s3:::example bucket”
只是bucket本身,而不是其中的对象

“资源”:“arn:aws:s3:::example bucket/*”
只是bucket中的对象,而不是bucket本身

您可以编写两个策略语句,也可以组合资源,如下所示:

"Resource": [ 
  "arn:aws:s3:::example-bucket",
  "arn:aws:s3:::example-bucket/*" 
]
重要的安全注意事项:通过将
s3:Put*
与bucket和object ARN一起使用,您的策略可能违反了最小特权原则,因为您已隐式授予此用户
s3:PutBucketPolicy
,从而允许这些凭据更改bucket策略。可能还有其他类似的担忧。您可能不想给这些凭证太多的控制权



@PatNeedham注意到了我忽略的第二个问题,
AWS.S3()
构造函数希望将对象作为其第一个参数,而不是字符串。

“资源”:[“arn:AWS:S3:::admin blog assets”,“arn:AWS:S3::admin blog assets/*”]
Ty为此,我确实需要更新我的策略。现在它就像一个符咒!它现在可以工作了,我只需要包含apiVersion并更新我的策略