Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict cloudfront signed url (GET Request) to be accessed by my mobile application

I am trying to serve video files using Amazon cloudfront to my app users using signed urls. I have created the signed urls using the documentation and it works perfectly well. The url generated has the signature, expires and keypair_id.

issues

What I am trying to achieve is to serve the video files to the user only when the request is coming in from my particular mobile application. I am looking for a solution to authorize the request (on a signed url) on the cloudfront side.

So if a user tries to access the signed url using our mobile app, we would want to serve the content but if the url is accessed from either web or any other mobile client we would like to raise an authorization error or 404.

I have went through the documentation and a couple blogs looking to achieve the above and everyone has pointed me in the direction to use signed urls which I already am. But the urls are still accessible directly via the browser.

Also I would like to know, why does a signed url has signature as a GET parameter, as if the signature is removed the content is still accessible using the url without the get query params.

Signed Url: http://d2z7g8y6l5f1j0.cloudfront.net/test_upload.mp4?Expires=1456828601&Signature=R3tljkRxGM9se2S4IJT908sT2BBGNJkpWE9IE-v1GAt-QY0WcaEVEY-OYvSSlhFK1ueNcWhgAscJQ7J~qUKZUt3XS5raKU3kj9STKYYzCemRRm1j5DE8XfhjRKRggSSw138F0lr~tDt~TLoJ7Pj9NNvoGl42jNNLaET7~d9pkAGAh-sNpoS1gz~d0CZTo41ZTFMIzshgZNxrWpCOR0PrLHfRALy2H9-Z9w4XfU4v66WEseVQ3FWyeXFyV0UO2S-KIXbe1ODiHFC6Ae6AJlWzoFfIGAxiLymmtUMJgeQHnu80u97ysMbbNYvek-S0tQBkkID3zC~tDQH~EjXPYcNUbA__&Key-Pair-Id=APKAINPV56WSGDECRTPQ

^^^ Serves the content

Original Url: http://d2z7g8y6l5f1j0.cloudfront.net/test_upload.mp4

^^^ Still serves the content

What's the difference in the above urls ?

Further Issue

The signed url that I have generated is still serving the content so what is the point of the expires GET query parameter, or the issue is that I have made the url correctly or not.

I followed the following method to generate my signed url:

from boto.cloudfront import CloudFrontConnection
from boto.cloudfront.distribution import Distribution

# establish cloudfront connection
cloudfront_connection = CloudFrontConnection('AWS_KEY', 'AWS_SECRET')
expiry_time = int(time.time() + 3000)

#get the distribution
distribution = Distribution(connection = cloudfront_connection, domain_name = '<specified_domain_name>', 'id' = '<specified distribution id>')

#create signed url
signed_url = distribution.create_signed_url(url = '<cloudfront_url>', keypair_id = '<cloudfront keypair_id>', expire_time = expiry_time, private_key_file = open('<location>', 'r'))
like image 637
Arpit Goyal Avatar asked Mar 01 '16 11:03

Arpit Goyal


Video Answer


1 Answers

I have went through the documentation and a couple blogs looking to achieve the above and everyone has pointed me in the direction to use signed urls which I already am. But the urls are still accessible directly via the browser.

Perhaps you have a misunderstanding of the signed URL feature. Any client that has the URL can access the content - there's nothing limiting it to a specific mobile browser or desktop browser or anything else. So long as the URL is valid (e.g. is within the validity period/has not expired, and is within the IP range that you specified, etc), any client will be allowed access.

Your application should generate the signed URL in real time when the user requests it, and it should expire within a time frame that is acceptable to you. This is explained in the docs under How Signed URLs work.

Also I would like to know, why does a signed url has signature as a GET parameter, as if the signature is removed the content is still accessible using the url without the get query params.

You can set up a cache behavior that restricts access to requestors that have valid signed URLs. To summarize, when you set up the distribution, you can configure various cache behaviors based on the path that the user is requesting.

This topic is a bit buried in the documentation. See the docs on Cache Behavior Settings, and in particular the Path Pattern and Restrict Viewer Access subsections.

like image 145
Ben Whaley Avatar answered Oct 24 '22 06:10

Ben Whaley