【发布时间】:2017-04-11 08:34:42
【问题描述】:
我正在生成一个预签名 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;
}
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
当我尝试在浏览器中打开任何返回的链接时,我收到来自 S3 的拒绝访问错误:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>A37839BB23186F72</RequestId>
<HostId>
yvKTN+CN1TTNk2tqoxxm3MPOGTUSMaRYtbbEFeCzGP7ou5IYf37Z9uBESwUQWDIUR1GUuPbZyuM=
</HostId>
</Error>
我想要提供访问权限的文件位于包含允许公共访问的文件夹的存储桶中,而我尝试访问的文件夹是私有的(称为 /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*"
}
]
}
据我了解,创建预签名 URL 的目的是允许未经身份验证的用户临时访问受保护的文件,而无需修改存储桶或文件夹权限。
有没有人知道我错过了什么或做错了什么?
谢谢!
【问题讨论】:
-
您在哪里授予与此 AWS 访问密钥 ID 关联的 IAM 用户执行
s3:GetObject的必要权限? -
您可以尝试使用AWS Command-Line Interface (CLI) 生成预签名的 URL,以确认权限有效吗?要使用的命令是
aws s3 presign。然后,比较 URL 以确保所有元素都匹配(但值会有所不同)。您提供的 URL 中的“过期”时间似乎不正确。预签名 URL 不依赖存储桶策略 - 它是提供访问权限的另一种方式。 -
@Michael-sqlbot - 我使用的是根访问密钥而不是特定的 IAM 用户。
-
等一下,@JohnRotenstein,“预签名 URL 不依赖存储桶策略——它是提供访问权限的另一种方式。”需要明确的是,它们不需要存储桶策略,但它们仍然服从存储桶策略(例如拒绝访问或授予拥有键)。
-
等一下...如何将整个查询字符串强制转换为小写?那肯定是无效的。我可以通过将有效的、有效的签名 URL 转换为全小写来复制这一点。
标签: php amazon-web-services amazon-s3 permissions sdk