访问被拒绝 - 使用预签名 URL 的 S3 资源 - PHP SDK

TGu*_*ond 5 php permissions sdk amazon-s3 amazon-web-services

我正在生成一个预签名 URL,以允许用户从 S3 存储桶下载文件。我使用以下代码通过 PHP SDK 生成 URL:

public static function get_content_link( $bucket, $key ) {

    //check response code from AWS
    require_once 'aws/aws-autoloader.php';

    $s3 = new Aws\S3\S3Client([
        'version' => 'latest',
        'region'  => 'eu-west-1',
        'credentials' => [
            'key'    => 'MY-KEY',
            'secret' => 'MY-SECRET',
        ],
    ]);

    $cmd = $s3->getCommand('GetObject', [
        'Bucket' => $bucket,
        'Key'    => $key
    ]);

    $request = $s3->createPresignedRequest($cmd, '+500 minutes');

    // Get the actual presigned-url
    $presignedUrl = (string) $request->getUri();

    return $presignedUrl;
}
Run Code Online (Sandbox Code Playgroud)

URL 将按预期返回,例如:

https://s3-eu-west-1.amazonaws.com/MY-BUCKET-NAME/product/3166_1480009917388.mov?x-amz-content-sha256=unsigned-payload&x-amz-algorithm=aws4-hmac-sha256&x-amz-credential=akiaiqrmkn276hcpjkaq%2f20161127%2feu-west-1%2fs3%2faws4_request&x-amz-date=20161127t145603z&x-amz-signedheaders=host&x-amz-expires=30000&x-amz-signature=98eaef504f053ca56908ac49c6539c4a8b8e250d7d3a4a12460f4a806ec41c19
Run Code Online (Sandbox Code Playgroud)

当我尝试在浏览器中打开任何返回的链接时,我收到来自 S3 的拒绝访问错误:

<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>A37839BB23186F72</RequestId>
  <HostId>
yvKTN+CN1TTNk2tqoxxm3MPOGTUSMaRYtbbEFeCzGP7ou5IYf37Z9uBESwUQWDIUR1GUuPbZyuM=
  </HostId>
</Error>
Run Code Online (Sandbox Code Playgroud)

我想要提供访问权限的文件位于包含允许公共访问的文件夹的存储桶中,我尝试访问的文件夹是私有的(称为 /product/)。我们的存储桶策略如下所示:

{
        "Version": "2008-10-17",
        "Statement": [
            {
                "Sid": "AllowPublicReadProxies",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "*"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::MY-BUCKET-NAME/proxies*"
            },
            {
                "Sid": "AllowPublicReadThumbs",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "*"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::MY-BUCKET-NAME/thumbs*"
            }
        ]
    }
Run Code Online (Sandbox Code Playgroud)

据我了解,创建预签名 URL 的目的是允许未经身份验证的用户临时访问受保护的文件,而无需修改存储桶或文件夹权限。

有没有人知道我错过了什么或做错了什么?

谢谢!

TGu*_*ond 4

非常感谢@Michael-sqlbot 为我解决了这个问题。

事实证明,在将预签名 URL 输出到页面时,我强制整个 URL 为小写,因此 AWS 返回了“访问被拒绝”错误,因为该资源在技术上并不存在。