Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't sign cloudfront URLs using boto

I've written the following code to sign URLS using boto, however, I'm unable to access the signed URLS. Any help would be greatly appreciated.

con = cloudfront.CloudFrontConnection(
    settings.AWS_USER_DETAILS.access_key_id,
    settings.AWS_USER_DETAILS.secret_key_id,
)

identities = con.get_all_origin_access_identity()

if len(identities) < 1:
    oai = con.create_origin_access_identity(
        'cv-oai',
        'OAI signing iOS video requests'
    )
else:
    oai = con.get_all_origin_access_identity()[0]

distro_summary = con.get_all_distributions()[0]
distro_info = con.get_distribution_info(distro_summary.id)

bucket = boto.connect_s3(
    settings.AWS_USER_DETAILS.access_key_id,
    settings.AWS_USER_DETAILS.secret_key_id,
    host='s3-eu-west-1.amazonaws.com'
).get_bucket(u'cv-video')

key_str = video.video_url.split('/')[-1]
key = bucket.get_key(key_str)

key.add_user_grant("READ", oai.s3_user_id)

distro = distro_summary.get_distribution()

# For local testing
if ip_addr == '127.0.0.1':
    ip_addr = None

private_key_string = open(settings.CF_PRIV_KEY_LOC).read()
print private_key_string

signed_url = distro.create_signed_url(
    "https://%s/%s" % (distro_info.domain_name, key_str),
    'APKAI3I3QZ7I73OIQIXA',
    expire_time=int(time.time()) + video.video_length + 5 * 60,
    #valid_after_time=None,
    #ip_address=ip_addr,
    #policy_url=None,
    private_key_string=private_key_string
)

Error:

Update: This is the error received when visiting the URLs generated by the above code. I am unable to find documentation of the CloudFront errors to determine why this might be happening.

<Error>
<Code>InvalidKey</Code>
<Message>Unknown Key</Message>
</Error>

Example URL:

https://d1xvt07pr26drp.cloudfront.net/2iwjz3wn9atqlfw4.mov?Expires=1388705061&Signature=auPWW-X1LzZJkPxJ5YPCqQMatchbAb3BxCWTG5oMY78G6LrH0sZiQL6EKdCX-l3Fi9E475b11uFL~HnxfBUY9QqQH86478QU5BnpmR-U7uEikRs7kTDWOVj4Riv3PHUmjmzlBW8xU7-n9C0m2UZSXedPsYYFdPoWHH0VLlyKk2TzgYydLqu~jtq0iNdmz-C9TOgUCaICiMYi082AVc7bt6xTfVszA9BeAD4KLKnr42raFDLojbA78Q-7bLNA2CiStdT-8BblQOQ5IXUCxYdkw7ak0vp77vER1pCG9cEBkCHD~9dZccyQEGJApO~ax4D5wDtCpeQj3l0pW6kYNUlP8Q__&Key-Pair-Id=APKAI3I3QZ7I73OIQIXA

The key pair is definitely active:

Key Pair is active

There is only one Origin Access Identity and one distribution:

[<boto.cloudfront.identity.OriginAccessIdentitySummary object at 0x10f356110>]
[<boto.cloudfront.distribution.DistributionSummary object at 0x10f356090>]
like image 418
Prydie Avatar asked Jan 02 '14 23:01

Prydie


People also ask

How do I sign into my CloudFront URL?

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.

How do I generate private URL with CloudFront?

Go to the AWS account security credentials page. Expand “CloudFront key pairs” and click the “Create New Key Pair” button. From the opened dialog, download and save the generated private key file and public key file. Close the dialog, and save the “Access Key ID” of the key pair you just generated.

What is the difference between CloudFront signed URL and S3 signed URL?

Both S3 and CloudFront have URL signing features that work differently. However, only S3 refers to them as Pre-signed URLs; CloudFront refers to them as Signed URLs and Signed Cookies. Note the service names in the URLs, in the documentation below.


Video Answer


1 Answers

I had the same issue.

I wondered if couldfront and s3 had not yet been connected logically to the "origin access identity." This is the identity that cloudfront uses to pull content from S3, verifying signatures with the private key pair you specified.

Sure enough, that was the problem. Disable public access to the underlying S3 bucket, then tell AWS to use the appropriate identity, then try your code again.

Here's how from the Web:

From the CloudFront dashboard (https://console.aws.amazon.com/cloudfront/home), click on "Distribution" on the left to see all your distros. Select the one you want, clicking the [i] icon for more information. From there, click on the [Origins] tab and select the radio button next to your bucket. Click it, and an Edit button will appear. Click Edit. Choose "Restrict Bucket Access" in the new panel that appears. The site will prompt you for which access identity to do. Choose the identity you created. Click "Yes, Edit" to save your changes.

Good luck!

like image 132
Scott Penberthy Avatar answered Oct 03 '22 11:10

Scott Penberthy