默认情况下如何使AWS S3存储桶中的所有对象公开?


151

我正在使用PHP库将文件上传到存储桶。我已将ACL设置为public-read-write,并且工作正常,但文件仍然是私有的。

我发现,如果将“ 受赠方”更改为“所有人”,则会使文件公开。我想知道的是如何将存储桶中所有对象默认Grantee设置为“ Everyone”。还是有另一种默认情况下使文件公开的解决方案?

我正在使用的代码如下:

public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
    if ($input === false) return false;
    $rest = new S3Request('PUT', $bucket, $uri);

    if (is_string($input)) $input = array(
        'data' => $input, 'size' => strlen($input),
        'md5sum' => base64_encode(md5($input, true))
    );

    // Data
    if (isset($input['fp']))
        $rest->fp =& $input['fp'];
    elseif (isset($input['file']))
        $rest->fp = @fopen($input['file'], 'rb');
    elseif (isset($input['data']))
        $rest->data = $input['data'];

    // Content-Length (required)
    if (isset($input['size']) && $input['size'] >= 0)
        $rest->size = $input['size'];
    else {
        if (isset($input['file']))
            $rest->size = filesize($input['file']);
        elseif (isset($input['data']))
            $rest->size = strlen($input['data']);
    }

    // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
    if (is_array($requestHeaders))
        foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
    elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
        $input['type'] = $requestHeaders;

    // Content-Type
    if (!isset($input['type'])) {
        if (isset($requestHeaders['Content-Type']))
            $input['type'] =& $requestHeaders['Content-Type'];
        elseif (isset($input['file']))
            $input['type'] = self::__getMimeType($input['file']);
        else
            $input['type'] = 'application/octet-stream';
    }

    // We need to post with Content-Length and Content-Type, MD5 is optional
    if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
        $rest->setHeader('Content-Type', $input['type']);
        if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);

        $rest->setAmzHeader('x-amz-acl', $acl);
        foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
        $rest->getResponse();
    } else
        $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');

    if ($rest->response->error === false && $rest->response->code !== 200)
        $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
    if ($rest->response->error !== false) {
        trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
        return false;
    }
    return true;
}

Answers:


299

转到http://awspolicygen.s3.amazonaws.com/policygen.html 填写详细信息,例如:在此处输入图片说明 在操作中,选择“ GetObject”,选择“ Add Statement”,然后选择“ Generate Policy”。

复制文本示例:

{
  "Id": "Policy1397632521960",
  "Statement": [
    {
      "Sid": "Stmt1397633323327",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucketnm/*",
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

现在转到您的AWS S3控制台,在存储桶级别,单击属性,扩展权限,然后选择添加存储桶策略。将上面生成的代码粘贴到编辑器中,然后单击保存。

默认情况下,存储桶中的所有项目都是公开的。


8
这是正确的回答。与以前的答案不同,这篇文章还教会了我如何创建策略以及它们的作用。阅读此内容后,我可以手动编写策略。
杰森·谢拉丹

2
我赞成这个答案的原因与@liyicky相同,详细说明是一个不错的介绍,而不仅仅是获得答案。
brendo

同样在这里。AWS有时会变得不透明,这可能是有充分原因的。从零开始,这种形式的答案很有帮助。
杰罗姆(Jerome)2015年

当您将新文件添加到存储桶但我需要更改存储桶中已经存在的文件才能公开时,此方法有效。
Radenko Zec

137

如果要在默认情况下将所有对象公开,则最简单的方法是通过存储桶策略而不是通过在每个对象上定义的访问控制列表(ACL)来实现。

在此处输入图片说明

您可以使用AWS Policy Generator为您的存储桶生成存储桶策略。

例如,以下策略将允许任何人读取S3存储桶中的每个对象(只需替换<bucket-name>为存储桶的名称):

{
  "Id": "Policy1380877762691",
  "Statement": [
    {
      "Sid": "Stmt1380877761162",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<bucket-name>/*",
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

存储桶策略包含一个列表,Statements每个语句都有一个EffectAllowDeny),该列表ActionsPrincipal(用户)在指定的Resource(由Amazon Resource Name或标识)上执行ARN

Id仅仅是一个可选的政策id和Sid是一个可选的唯一语句ID。

对于S3存储桶策略,资源ARN采用以下形式:

arn:aws:s3:::<bucket_name>/<key_name>

上面的示例允许(Effect: Allow)任何人(Principal: *)访问(Action: s3:GetObject)存储桶(Resource: arn:aws:s3:::<bucket-name>/*)中的任何对象。


控制面板有办法吗?
ianaz 2014年

2
@ianaz您可以通过AWS控制台(控制面板)将此存储桶策略添加到存储桶
dcro 2014年

@ianaz在下面看到我的答案。
jaxxbo 2015年

还要注意,上面的链接中有一个“示例策略”链接,该链接提供了剪切和粘贴到策略生成器中所需的确切信息。随着AWS更新API,这更有可能保持正确。今天早上对我来说就像是一种魅力。
keithpjolley

Principal: *对我有很大帮助。谢谢!
iedmrc

2

我的问题稍有不同,但是由于此问题位于google搜索的顶部,因此我将保留我的解决方案,也许会对某些人有所帮助。

我之前已经可以完全访问S3存储桶,但是有一天它才开始返回Access Denied我所有的文件。解决方案非常简单。

  1. 转到Services-S3
  2. 单击您的S3存储桶
  3. 切换至Permissions标签页,然后转到Bucket Policy标签页
  4. 然后单击Save按钮。

它应该为您的所有文件重新分配权限。

在此处输入图片说明

无论如何,这里已满bucket policy,可以公开所有对象

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::enter-here-your-media-bucket-name/*"
        }
    ]
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.