设置S3存储桶策略

7
我正在建设一个网站,用户可以直接上传文件到Amazon S3。我会暂时使用我的秘钥签署网址,授予用户暂时的将文件上传至我的站点的PUT权限,这是通过CORS配置实现的。
现在,一旦文件上传到那里,我希望没有人能阅读它们,只有我可以。我当前设置的存储桶策略不允许任何人读取对象,包括我这个管理员,这非常不好。请问什么样的存储桶策略能够解决这个问题?
以下是我的有效CORS配置。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://url.com</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

更新: 适用于此政策:

 {
        "Version": "2008-10-17",
        "Statement": [
            {
                "Sid": "AllowPublicRead",
                "Effect": "Deny",
                             "NotPrincipal": {
                                "AWS":"arn:aws:iam::123456789012:user/Bob"
                             }
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::<bucket>/*"
            }
        ]
    }
1个回答

5

好的,我们创建了一个拥有对S3完全权限的IAM用户,我们使用此用户来签署临时策略以允许上传。用户的策略为(您可以进一步限制此用户仅允许访问一个存储桶,甚至进一步允许用户仅对存储桶进行放置权限):

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

我们随后创建了一项临时策略,以允许将上传内容放入我们的"useruploads"存储桶中。
{ "expiration": "2013-11-20T12:00:00.000Z",
  "conditions": [
    {"bucket": "useruploadtest"},
    ["starts-with", "$key", "russ"], 
    {"acl": "public-read"}, 
    {"success_action_redirect": "http://localhost/successful_upload.html"},
    ["starts-with", "$Content-Type", "image/"],
  ]
}

我们使用秘钥来对base64编码的策略进行签名(以下代码示例展示了如何使用cryptojs创建签名,但请勿将您的秘钥放在客户端代码中)。
  <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js">    </script>
  <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
  <script>
    var hash = CryptoJS.HmacSHA1("eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTAxVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJ1c2VydXBsb2FkdGVzdCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJydXNzIl0sIA0KICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIn0sIA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2xvY2FsaG9zdC9zdWNjZXNzZnVsX3VwbG9hZC5odG1sIn0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLA0KICBdDQp9", "YourSecretKeyHere");
    var base64 = CryptoJS.enc.Base64.stringify(hash);
    console.log(base64);
  </script>

然后,您可以使用签名策略来允许临时上传。
<form action="http://useruploadtest.s3.amazonaws.com" method="post" enctype="multipart/form-data">
    <input type="hidden" name="acl" value="public-read" />
    <input type="hidden" name="success_action_redirect" value="http://localhost/successful_upload.html" />
    <input type="hidden" name="AWSAccessKeyId" value="AKIAJM3U7AMGF6J6YYWQ" />
    <input type="hidden" name="Policy" value="eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTAxVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJ1c2VydXBsb2FkdGVzdCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJydXNzIl0sIA0KICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIn0sIA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL2xvY2FsaG9zdC9zdWNjZXNzZnVsX3VwbG9hZC5odG1sIn0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLA0KICBdDQp9" />
    <input type="hidden" name="Signature" value="Db4K65tz/WJtjAUUCWRn5MXdAJ4=" />


    Key to upload: <input type="input" name="key" value="test.jpg" /><br />
    Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
    File: <input type="file" name="file" /> <br />

    <input type="submit" name="submit" value="Upload to Amazon S3" />
  </form>

只要我们的“useruploadtest”存储桶允许另一个IAM用户读取文件并进行处理,我们在应用程序中使用该用户即可正常运行。
希望这能帮到你。

我按照您的要求创建了一个额外的用户,并附加了您提供的用户策略。但是在上传时仍然出现403错误。我也使用新的访问密钥对URL进行签名。当我删除策略后,就可以上传(很奇怪...)。我需要另外指定存储桶策略并指定正确的授权对象吗? - The Internet
弄清楚Grantees与IAM用户的关系,以及IAM用户策略如何与存储桶策略配合工作,以及如何指定适当的存储桶策略是一件非常麻烦的事情。 - The Internet
哎呀,太糟糕了,我的帖子有问题,伙计。我正在检查一些东西,稍后会更新。 - rabs
我认为你还需要包括动作 "Action":"s3:PutObjectAcl"。但这仍然无法阻止所有人公开地读取存储桶。 - The Internet
是的,我没有包括正确的操作,并且我也没有包括如何生成临时策略并签署它。 - rabs
显示剩余3条评论

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