I have audio files stored at Amazon S3 which are accessed from a web based music player app and also from mobile apps. Even non signed in users should be able to access the
You can restrict access based on the HTTP referrer. It's not bulletproof (Referrer can be spoofed) but it will stop casual downloads.
You use a bucket policy to restrict the possible values for Referrer.
There's an example on this page (scroll down a bit) http://docs.aws.amazon.com/AmazonS3/latest/dev/AccessPolicyLanguage_UseCases_s3_a.html
Here's their example:
{
"Version":"2008-10-17",
"Id":"http referer policy example",
"Statement":[
{
"Sid":"Allow get requests originated from www.example.com and example.com",
"Effect":"Allow",
"Principal":"*",
"Action":"s3:GetObject",
"Resource":"arn:aws:s3:::examplebucket/*",
"Condition":{
"StringLike":{
"aws:Referer":[
"http://www.example.com/*",
"http://example.com/*"
]
}
}
}
]
}
You could also do signed URLs that expire - that would stop people from LINKING to your content from other site.
One scenario comes to mind:
When your music player app wants to play something, it has to ask your backend for the URL to the MP3. Your backend can produce URLs with "Expires" parameter[1] set to 10 seconds in the future.
This way, the URL returned by your backend is only usable for 10 seconds, which should be more than enough for the music player to initiate the download from S3.
Of course the user could download the file if he/she sees the URL in some kind of HTTP sniffer in the 10 second window and starts the download.
But there's no bulletproof way to protect user from getting his/hers hands on the content their device accesses. If the content is delivered to a device, there is always a way for sufficiently technical people to get their hands on it.
p.s. Just a heads-up, if your MP3 player supports seeking (especially seeking by sending another HTTP range-request), you'd have to re-get a new URL with refreshed "expires" parameter from your backend.
[1] http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
I've come across this requirement too and have a more updated answer on how to achieve this.
On your bucket's "Permission" tab, select the "Bucket Policy" button and fill with the code below:
{
"Version": "2012-10-17",
"Id": "Policy1542209806458",
"Statement": [
{
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::your-bucket-arn/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://yourdomain.com/*"
]
}
}
}
]
}
This will allow only requests with the referer from your domain. Be aware to set your Resource
field and change the allowed aws:Referer
list.
This can still be spoofed but it's a simple barrier for direct linking your S3 objects.