The scenario:
Amazon S3 folder with private files
Goal: display videos on a HTML5 player, on a specific domain, without turning these files public (similar to vimeo allowing to embed a video only on a domain)
I already tried to change the bucket policy but without success!
You'll want to set these files to private.
You'll want to use pre-signed URLs to get the correct authentication token that is required for you to view the files after they're set to private.
If your player is web-based, you'll probably want to enable a CORS configuration.
Related
Using the cloudfront to read and write in the same S3 bucket, how can I prohibit a user from using a read-presigned url to make an injection (upluad)?
Thanks.
Deny access to PUT for cloudfront and it won't be able to put data into s3. In s3 permissions you can allow read only calls from cloudfront only. Turn off public access on s3, to make sure it will allow gets only from cloudfront. On CloudFront use this to update s3 bucket access, before this disable any public access on s3. CF will update S3's policy & create CF origin access identity:
To put data into S3, use presigned URL and it all goes down to the place where you create the presigned URL for upload. You may have api gateway RESTfull tiny api which would authenticate user to get the upload url and would return the upload url, which would be used by user to upload data to S3.
I'm using custom domain and CloudFront for S3 static hosting site to serve https.
It's working fine when I open the pages through the app's internal buttons or link,
but if I input direct URL in the address bar, or click the browser refresh button, it shows
This XML file does not appear to have any style information associated with it. The document tree is shown below.... Access Denied error screen.
I searched related answers and tried to /index.html in the CloudFront general setting as Default Root Object but it didn't work. (Before this try, it was index.html)
When I updated it as /index.html, even the domain itself didn't work.
I have another S3 static hosting site without CloudFront and certificate just for testing.
This site is working fine even I input direct url or click the refresh button.
Above two S3 bucket have same settings (root object is index.html and error document is also index.html)
After this, I changed CloudFront Origin Domain Name from REST endpoint to website endpoint referred to this docs (https://aws.amazon.com/premiumsupport/knowledge-center/s3-website-cloudfront-error-403/)
But now getting this error when I refresh the screen.
All the object in S3 is owned to bucket owner and has public access.
This app is made by React and using react-router-dom.
Could you give me any hint or advice?
Thanks.
Solved...
My S3 bucket region requires . instead of - when I use website endpoint for cloudfront.
And FYI..
In my case, there are some little difference with the document and some tutorial. My CloudFront distribution doesn't need to use default root object, and individual objects in S3 has no public access but the bucket has it.
There are some specific endpoints to be used for website hosting buckets, which are listed in the Amazon Simple Storage Service endpoints and quotas document. For example, when hosting in eu-west-1, cloudfront will prepopulate the dropdown with example.s3.eu-west-1.amazonaws.com, but if you look into the bucket settings, Static website hosting section, it will show you the correct url example.s3-website-eu-west-1.amazonaws.com
Carefully read the table! The url scheme is not fully consistent, eg. s3-website.us-east-2.amazonaws.com but s3-website-us-east-1.amazonaws.com - just to make your day a bit more joyful.
So I had the exact same issue and was able to resolve it after taking the s3 bucket endpoint located in the properties of the s3 bucket and then pasting it into the cloudfront origins section into the origin domain. I removed the beginning of the endpoint for example: "http://website.com.s3-website.us-east-2.amazonaws.com" you would just remove the "http://" and then post the rest into the cloudfront origin domain and click save. That should solve the problem!
I tried all kinds of different options such as making sure every object was public as well in the s3 bucket. Make sure your s3 bucket is also publicly available.
Certain regions do have different endpoints for your s3 buckets. Here is a link that shows more of that: https://aws.amazon.com/premiumsupport/knowledge-center/s3-rest-api-cloudfront-error-403/
I've uploaded a file using the SDK to my private S3 bucket.
I can access this file through the S3 UI.
However, I cannot access this file through a direct link. It gives me some XML that includes "AccessDenied" as a code and message.
It seems reasonable that since I'm authenticated in the browser and am clicking on a direct link to the file from the same browser, that I should be allowed through. At the very least, I should be directed to a login page.
Does anyone have any experience with this?
So after working on this for a bit, I discovered the best thing is to simply publish the console URL to the file.
https://s3.console.aws.amazon.com/s3/object/{your bucket}/{your file path}?region={the region of your bucket}&tab=overview
Be mindful to specify the correct region. If you're forming this programmatically, then use Amazon.RegionEndpoint.SystemName.
If you're not logged in, it will ask you for your login!
No signed URL is necessary.
Thanks to everyone who contributed!
There are 2 places that you need to make sure are set correctly based on how you want to setup access to the bucket. It will either have public or private access.
The properties tab:
Here you can set what you will use the bucket for.
The Permissions tab -> Bucket Policy:
With this, you can then setup access. I was able to generate a policy with this site:
http://awspolicygen.s3.amazonaws.com/policygen.html
EDIT:
Mine is working with the settings I have shown. I recommend asking the AWS boards if to get to the bottom of it. You could also try this:
You can use the direct link if you are inside a VPC. You have to :
1- Create a VPC endpoint for Amazon S3.
2- Add a bucket policy that allows access from the VPC endpoint.
All steps are described in the following link :
https://aws.amazon.com/premiumsupport/knowledge-center/s3-private-connection-no-authentication/?nc1=h_ls
I'm currently looking to host an app with the Angular frontend in a AWS S3 bucket connecting to a PHP backend using the AWS Elastic Beanstalk. I've got it set up and it's working nicely.
However, using S3 to create a static website, anyone can view your code, including the various Angular JS files. This is mostly fine, but I want to create either a file or folder to keep sensitive information in that cannot be viewed by anyone, but can be included/required by all other files. Essentially I want a key that I can attach to all calls to the backend to make sure only authorised requests get through.
I've experimented with various permissions but always seems to be able to view all files, presumably because the static website hosting bucket policy ensures everything is public.
Any suggestions appreciated!
Cheers.
The whole idea of static website hosting on S3 means the content to be public, for example, you have maintenance of your app/web, so you redirect users to the S3 static page notifying there is maintenance ongoing.
I am not sure what all have you tried when you refer to "experimented with various permissions", however, have you tried to setup a bucket policy or maybe setup the bucket as a CloudFront origin and set a Signed URL. This might be a bit tricky considering you want to call these sensitive files by other files. But the way to hide those sensitive files will either be by using some sort of bucket policy or by restricting using some sort of signed URL in my opinion.
I'm thinking about whether to host uploaded media files (video and audio) on S3 instead of locally. I need to check user's permissions on each download.
So there would be an action like get_file, which first checks the user's permissions and then gets the file from S3 and sends it using send_file to the user.
def get_file
if #user.can_download(params[:file_id])
# first, download the file from S3 and then send it to the user using send_file
end
end
But in this case, the server (unnecessarily) downloads the file first from S3 and then sends it to the user. I thought the use case for S3 was to bypass the Rails/HTTP server stack for reduced load.
Am I thinking this wrong?
PS. I'm using CarrierWave for file uploads. Not sure if that's relevant.
Amazon S3 provides something called RESTful authenticated reads, which are basically timeoutable URLs to otherwise protected content.
CarrierWave provides support for this. Simply declare S3 access policy to authenticated read:
config.s3_access_policy = :authenticated_read
and then model.file.url will automatically generate the RESTful URL.
Typically you'd embed the S3 URL in your page, so that the client's browser fetches the file directly from Amazon. Note however that this exposes the raw unprotected URL. You could name the file with a long hash instead of something predictable, so it's at least not guessable -- but once that URL is exposed, it's essentially open to the Internet. So if you absolutely always need access control on the files, then you'll need to proxy it like you're currently doing. In that case, you may decide it's just better to store the file locally.