亚马逊 S3 复制对象权限

30

我拥有一个拥有所有权限的用户。

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

我正在使用aws-sdk-php-2在存储桶中上传和复制对象。

http://docs.aws.amazon.com/aws-sdk-php-2/latest/class-Aws.S3.S3Client.html

上传代码运行完美。

                $client->putObject(array(
                'Bucket'     => 'kiosk',
                'Key'        => 'test/orders/test.csv',
                'SourceFile' => $sourcePath,
            ));

检查对象是否通过https://console.aws.amazon.com/s3在S3上创建,然后我执行下一个脚本。

        $result = $client->copyObject(array(
        'Bucket' => 'kiosk',
        'CopySource' => 'test/orders/test.csv',
        'Key' => 'test/test.csv',
    ));

而且我正在遇到致命错误:

Fatal error: Uncaught Aws\S3\Exception\S3Exception: AWS Error Code: AllAccessDisabled, Status Code: 403, AWS Request ID: XXX, AWS Error Type: client, AWS Error Message: All access to this object has been disabled, User-Agent: aws-sdk-php2/2.2.1 Guzzle/3.3.1 curl/7.19.7 PHP/5.4.13 thrown in phar:///usr/share/pear/AWSSDKforPHP/aws.phar/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 89

在手动上传文件到console.aws.amazon.com/s3后,尝试复制时出现了不同的错误:

Fatal error: Uncaught Aws\S3\Exception\AccessDeniedException: AWS Error Code: AccessDenied, Status Code: 403, AWS Request ID: XXX, AWS Error Type: client, AWS Error Message: Access Denied, User-Agent: aws-sdk-php2/2.2.1 Guzzle/3.3.1 curl/7.19.7 PHP/5.4.13 thrown in phar:///usr/share/pear/AWSSDKforPHP/aws.phar/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 89
我也尝试着通过 console.aws.amazon.com/s3 对文件和文件夹设置权限: 被授权者:所有人,开放/下载和查看权限以及编辑权限, 但仍然出现同样的错误。

当我尝试访问S3中的对象时,我遇到了相同的错误消息...你找到答案了吗? - insanepaul
对于其他遇到这个问题的人,我想分享我的解决方法 - 我的问题是使用一个用户帐户上传了一个文件,然后尝试使用另一个用户复制它,结果出现了访问拒绝错误。 - christian.thomas
3个回答

93

我知道这是一个老问题,但最近在处理一个遗留项目时,我遇到了相同的问题。

$this->client->copyObject([
    'Bucket'        => $this->bucket,
    'CopySource'    => $file,
    'Key'           => str_replace($source, $destination, $file),
]);

我的所有S3调用都能正常使用,除了copyObject一直抛出ACCESS DENIED错误。经过一番探索,我终于找到了原因

AWS v2 SDK CopySource Documentation

我只传递了键(key),并假设传递的bucket名称是源和目标都会使用的,这是一个错误的假设。源必须有bucket名称前缀。

以下是我的解决方案:

$this->client->copyObject([
    'Bucket'        => $this->bucket,
    // Added the bucket name to the copy source
    'CopySource'    => $this->bucket.'/'.$file,
    'Key'           => str_replace($source, $destination, $file),
]);

出现“访问被拒绝”的提示是因为系统认为您输入的密钥/文件夹名称中的第一部分实际上是存储桶的名称,而这个存储桶可能不存在或者您没有权限访问。


3
当使用aws cli的aws s3api copy-object命令时,同样的情况也会发生。即使您已经在--bucket参数中指定了存储桶名称,并且正在同一存储桶内复制对象,您仍然需要在--key参数中再次提供存储桶名称。请注意不要改变原文的意思。 - Raghu Dodda
谢谢,它对我有效。但是无法获得结果响应。 - Kelvin
避免在键名前面加上斜杠。 - eckymad
1
你是绝对的救星。我已经调试了约一个小时,但我可能会花更多时间。谢谢。顺便说一下,在创建新的“Key”时不需要存储桶名称,只需要“CopySource”。 - Jamie
3
不错。我没有注意到文档中有这个提示 CopySource: "/sourcebucket/HappyFacejpg", - Vyacheslav Tsivina

25

我找到了这里的问题;作为一个AWS新手,在我意识到每个设置的用户策略需要清楚地允许您使用的服务之前,我在这里挣扎了一段时间。

在这种情况下,我没有设置允许用户进入S3。

转到IAM,然后转到用户并单击具有您正在使用的凭据的特定用户。从那里进入权限选项卡,然后单击附加用户策略并在选择策略模板下找到S3策略。这应该可以解决您的问题。

希望能帮助到您!


2
我尝试过但仍然遇到了AWS错误代码:AccessDenied 错误类型:客户端,请问有什么建议吗? - mithra

6

受欢迎的答案是正确的,但仍存在问题。必须包括ACL选项。

$this->client->copyObject([
  'Bucket'        => $this->bucket,
  // Added the bucket name to the copy source
  'CopySource'    => $this->bucket.'/'.$file,
  'Key'           => str_replace($source, $destination, $file),
  'ACL'           => 'public-read'
]);

ACL可以是以下值之一:'ACL' => '私有|公共读取|公共读写|经过身份验证的读取|aws-exec-read|bucket-owner-read|bucket-owner-full-control'


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