AWS S3 - 配置网站访问权限

3
我一直在关注这个教程:https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html#s3-example-photo-album-scenario-prerequisites。将来,它将被修改为管理音频文件而不是图像。
我按照指南进行了操作,但可能错过了某些步骤,因为当尝试列出对象时,仍然遇到了拒绝访问错误。
我在S3上创建了一个存储桶
- 它不是公共存储桶 - 区域是欧盟(伦敦),因此是eu-west-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个回答

3
我发现你的S3存储桶策略存在问题。listObjects调用需要在存储桶上设置权限,而不是在其中的对象上设置权限。
简而言之,你需要将"arn:aws:s3:::thisusesmybucketname"添加到你的资源声明中,使其如下所示:
{
  "Version": "2012-10-17",
  "Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "s3:*"
        ],
        "Resource": [
            "arn:aws:s3:::thisusesmybucketname/*",
            "arn:aws:s3:::thisusesmybucketname"
        ]
    }
  ]
}

1
那就是它 - 像往常一样,当别人指出时似乎很容易。现在添加了这个,并收紧了桶策略以特定于 Referer,并且似乎所有问题都解决了,谢谢! - Reactive

0

你们都做得很好,一切都很完美。现在问题来了,你们制作了一个无服务器公共网站,展示了一些图片,任何人都可以使用AWS Cognito提供给他们的客户端临时凭证来查看这些图片。

但是你们没有给它们公共读取权限,那么他们怎么访问呢?

你们需要为想要公开展示的对象创建ACL(访问控制列表),将其设置为public-read,并在上传对象/图片时进行设置,这样只有你允许的对象才能被公众访问。如果你想让公众也能上传,则还需要提供写入权限。

另外,给存储桶提供公共读取权限并不意味着公众拥有你的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存储桶中以用户名为对象前缀的特定对象。

例如:
yourbucketname/user1/* 只能被user1访问

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接