Here is my sign URL function:
private function signUrl($lesson) {
$cloudFrontClient = AWS::createClient('CloudFront', [
'region' => '<my-region>',
'version' => '2017-03-25'
]);
$streamHostUrl = 'https://<mydomain>.cloudfront.net';
$resourceKey = $object->s3_video;
$expires = time() + 300;
// Create a signed URL for the resource using the canned policy
$signedUrlCannedPolicy = $cloudFrontClient->getSignedUrl([
'url' => $streamHostUrl . '/' . $resourceKey,
'expires' => $expires,
'private_key' => '<MY_PEM_FILE_PATH>',
'key_pair_id' => '<KEY_PAIR_ID>'
]);
return $signedUrlCannedPolicy;
}
When clicking on the link I get this ambiguous error message, which can't really help me debug the problem:
<Error><Code>AccessDenied</Code><Message>Access
Denied</Message><RequestId>SOME_ID_HERE</RequestId><HostId>SOME_BASE64_HERE_NOT_READABLE</HostId></Error>
I wondered if there is some way to debug this, maybe in the AWS console or some API call?
If your distribution doesn't have a default root object defined, and a requester doesn't have s3:ListBucket access, then the requester receives an Access Denied error. The requester gets this error instead of a 404 Not Found error when they request the root of your distribution.
In your CloudFront distribution, specify one or more trusted key groups, which contain the public keys that CloudFront can use to verify the URL signature. You use the corresponding private keys to sign the URLs. For more information, see Specifying the signers that can create signed URLs and signed cookies.
I discovered that “Access Denied” errors may show up when a CloudFront Distribution is set up under the following conditions: A private S3 Bucket is being used along with a S3 Origin in the CloudFront Distribution An Origin Access Identity is being used.
To see whats wrong with the generated CloudFront signed URL, try to base64 decode the policy value and see the Resource URL/expires etc are correct or not. hmm, possible to share a sample decode policy or response headers? I assume you also have the correct keypair-id (CloudFront not general AWS access key)
Why is CloudFront returning 403 Access Denied errors from Amazon S3? To troubleshoot Access Denied errors, determine if your distribution’s origin domain name is an S3 website endpoint or an S3 REST API endpoint. Follow these steps to determine the endpoint type:
Here's an overview of how you configure CloudFront and Amazon S3 for signed URLs and how CloudFront responds when a user uses a signed URL to request a file. In your CloudFront distribution, specify one or more trusted key groups, which contain the public keys that CloudFront can use to verify the URL signature.
There's more in that error than you see. Your CloudFront signed URL is actually working. <HostId>
and <RequestId>
are not components in an Access Denied error from CloudFront. This error is coming from S3, after CloudFront accepts your signed request.
In the HTTP response headers, you should see...
Server: Amazon S3
x-amz-request-id: (same value as the XML RequestId)
x-amz-id-2: (same value as the XML HostId)
S3 is not allowing CloudFront to fetch your content.
See Using an Origin Access Identity to Restrict Access to Your Amazon S3 Content and verify your configuration.
Also review the steps in Amazon CloudFront Latency to set your Error Caching Minimim TTL for 403 errors to 0 seconds, otherwise you will continue to see the error for up to 5 minutes (the default) after you fix the issue.
If everything looks correct, you may want to review your S3 bucket logs to ensure that you are requesting the object that you intend to. In CloudFront origin settings, there is a value called Origin Path that should almost always be left blank. Putting a value there will cause CloudFront to ask for a different object than the URL makes it appear you are requesting, so this value is not commonly something that you should set to anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With