I am generating a Pre Signed URL to allow users to download files from an S3 Bucket. I am generating the URL's via the PHP SDK using the following code:
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;
}
The URLs are being returned as expected, for example:
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
When I try to open any of the returned links in the browser I am getting an access denied error from S3:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>A37839BB23186F72</RequestId>
<HostId>
yvKTN+CN1TTNk2tqoxxm3MPOGTUSMaRYtbbEFeCzGP7ou5IYf37Z9uBESwUQWDIUR1GUuPbZyuM=
</HostId>
</Error>
The files that I want to provide access to are in a bucket which contains folders allowing public access, by the folder I am trying to access is private (called /product/). Our bucket policy looks like this:
{
"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*"
}
]
}
It is my understanding that the purpose of creating a Pre Signed URL is to allow unauthenticated users temporary access to protected files without having to modify the bucket or folder permissions.
Has anyone got any ideas as to what I have missed or done wrong?
Thanks!
s3:GetObject?aws s3 presign. Then, compare the URLs to ensure that all elements match (but the values will differ). Your 'expires' time seems incorrect in the URL you provided. The pre-signed URL does not rely on bucket policies -- it is an alternate way of providing access.