AWS S3 - 配置网站访问

时间:2018-05-22 13:31:18

标签: amazon-web-services amazon-s3

我一直在关注本教程:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html#s3-example-photo-album-scenario-prerequisites

最终会改变这种情况来管理音频文件而不是图像。

我已经按照指南进行操作但必须遗漏一些内容,因为在尝试列出对象时仍然会出现“拒绝访问”错误。

我在S3上创建了一个存储桶    - 它不是公共桶    - 地区是欧盟(伦敦)所以欧洲西部2  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>

访问控制列表仅显示对帐户(长数字/字母列表)的访问,包括列表,写入,读取存储桶和写入存储桶权限。

在Amazon Cognito控制台中我有一个标识池,标识池具有为未经身份验证和身份验证分配的角色,但我相信我只会使用未经身份验证的?

未经身份验证的角色具有以下政策:

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

然后在我的网站上我做了:

<script src="https://sdk.amazonaws.com/js/aws-sdk-2.243.1.min.js"></script>
<script type="text/javascript">

function getHtml(template) {
  return template.join('\n');
}

var albumBucketName = 'myactualname';
var IdentityPoolId = 'eu-west-2:lotsofcharacters';

AWS.config.update({
  region: 'eu-west-2',
  credentials: new AWS.CognitoIdentityCredentials({
    IdentityPoolId: IdentityPoolId,
  })
});

var s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  params: {Bucket: albumBucketName},
});

listAlbums();

function listAlbums() {
  s3.listObjects({Delimiter: '/'}, function(err, data) {
    if (err) {
      console.log(err.message);
      //return alert('There was an error listing your albums: ' + err.message);
    } else {
      // we never get here
    }
  });
}
</script>

我错过了什么吗?如果我回到存储桶并设置读/写的公共访问权限,那么它一切正常 - 但我理解这样做是错误的方式,因为它打开了任何人/每个人使用我的AWS ?

谢谢!

2 个答案:

答案 0 :(得分:1)

我发现您的S3存储桶策略存在问题。 listObjects调用需要在存储桶上设置权限,而不是在其中的对象上设置权限。

简而言之,您需要将"arn:aws:s3:::thisusesmybucketname"添加到您的Resource语句中,所以它看起来像这样:

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

答案 1 :(得分:0)

你们都做对了,一切都很完美。现在有了这个概念,您已经创建了一个无服务器的公共网站,其中显示了一些公开的人可以使用AWS Cognito为其浏览器提供的客户端临时凭证来查看的图像。 但是你没有给它公开读取权限,那么他们将如何访问它们?

您必须为上传对象/图片时希望公众看到公开阅读的对象设置 ACL ,即访问控制列表,以便任何人只能访问那些只允许你这样做的对象。如果你也希望公共上传,那么你也必须提供写访问权。

其他方面是对公共读取访问存储桶并不意味着公众对您的AWS账户拥有无限的权力,故意提供他们可以与您网站的存储服务进行交互的特定位置。

这是我如何做的代码:

var file = fileChooser.files[0];
if (file) {
    results.innerHTML = '';

var params = {
                    Key: 'maus/group1.jpeg',
                    ContentType: file.type,
                    Body: file,
                    ACL: 'public-read'
                };

                s3.putObject(params, function (err, data) {
                    if (err) {
                        results.innerHTML = 'ERROR: ' + err;
                    }else {
                        results.innerHTML = ' snapshot uploaded !!!';
                    }
                }).on('httpUploadProgress', function (progress) {console.log(progress);});
} else {

            results.innerHTML = 'Nothing to upload.';
        }

如果您想要更严格地控​​制存储桶,那么您可以使用经过身份验证的标识池来执行此操作,然后以特定用户可以访问s3中的特定对象的方式修改代码用户名作为他/她上传的对象前缀的存储桶。

e.g。
yourbucketname / user1 / * 仅供user1访问

未经身份验证的用户池本身意味着您希望每个人都使用临时凭据访问特定AWS资源