I have hosted my static files on Amazon bucket and configured them in settings but still they are not loading when I run the server and throwing the error as shown in the image:
Objects in Amazon S3 are private by default.
If you wish for your objects to be accessible, you will need to use one of these methods:
Attach a Bucket Policy to your Amazon S3 bucket that permits public access. See: Bucket Policy Examples - Amazon S3, or
Assign public-read permissions to the individual objects, or
Have your application generate an Amazon S3 pre-signed URLs, which grants time-limited access to an object.
The screenshot you provided shows URLs that in the format of a pre-signed URL. This is either because your application generated the pre-signed URL, or because you copied a link from within the Amazon S3 management console. These URLs expire after a given time period, which is ideal for security if you are providing temporary access to a private object.
However, if your intention is that these files should be accessible to anyone at any time, you should attach a Bucket Policy to the Amazon S3 bucket.
See also: Hosting a static website on Amazon S3
Related
I understand that you can grant read/write to internal AWS account resources like lambda when you turn off public access. However what if I need to be able to read an S3 object from an external host, via the S3 URL? Sure I know I could add a public API endpoint to serve up the S3 asset. However if I use something like <img src=""/> that doesn't help me. If I try to perform a GET on the S3 url at this point, I get a 403. I'm wondering in this case that I have to leave 'public access' on?
There are two ways to access objects in private Amazon S3 buckets.
Use S3 API calls
You can use API calls using the AWS CLI or an AWS SDK. These API calls require AWS credentials that have GetObject permission to access the bucket. They do not require the bucket to be public.
Use a pre-signed URL
Alternatively, you can generate an Amazon S3 pre-signed URL, which provides time-limited access to private objects in Amazon S3. The URL can be used in <img src=...> tags.
The pre-signed URL can be generated in a few lines of code without the need to call AWS. It is basically a hashed signature that uses some AWS credentials to authorise access to the private object. This option appears most suitable for your use-case.
Use Case:
I want to be able to:
Upload images and audio files from my backend to S3 bucket
List and view/play content on my backend
Return the objects URLs in API responses
Mobile apps can view/play the URLs with or without? authentication from the mobile side
Is that possible without making the S3 bucket public ?
Is that possible without making the S3 bucket public ?
Yes, it should be possible. Since you are using EC2 instance for backend, you, you can setup instance role to enable private and secure access of your backed application to S3. In the role, you would allow S3 read/write. This way, if your application is using AWS SDK, you can seamlessly access S3 without making S3 public.
Regarding the links to the object, the general way is to return S3 pre-signed links. This allows for temporary access to your objects without the need for public access. The alternative is to share your objects through CloudFront as explained in Amazon S3 + Amazon CloudFront: A Match Made in the Cloud. In either case, bucket can be private.
I have provided AmazonS3FullAccess policy for both the IAM user and group. Also the buket that I am trying to access says "Objects can be public". I have explicitly made the folder inside the bucket public. Despite all this I am getting access denied error when I tried to access it through its url. Any idea on this?
Objects in Amazon S3 are private by default. This means that objects are not accessible by anonymous users.
You have granted permission for your IAM User to be able to access S3. Therefore, you have access to the objects but you must identify yourself to S3 so that it can verify your identity.
You should be able to access S3 content:
Via the Amazon S3 management console
Using the AWS CLI (eg aws s3 ls s3://bucketname)
Via authenticated requests in a web browser
I suspect that you have been accessing your bucket via an unauthenticated request (eg bucketname.s3.amazonaws.com/foo.txt. Unfortunately, this does not tell Amazon S3 who you are, so it will deny the request.
To access content with this type of URL, you can generate an Amazon S3 pre-signed URLs, which appends some authentication information to the URL to prove your identity. An easy way to generate the URL is with the AWS CLI:
aws s3 presign s3://bucketname/foo.txt
It will return a URL that looks like this:
https://bucketname.s3.amazonaws.com/foo.txt?AWSAccessKeyId=AKIAxxx&Signature=xxx&Expires=1608175109
The URL will be valid for one hour by default, up to 7 days.
There are two ways I will recommend.
go to s3 dashboard, and download the object you need, one by one manually, the bucket can be kept private at the same time.
build a gateway/a small service, to handle authentication for you, set a policy and give the permission to the service container/lambda to visit the private bucket, and restrict only specific users to download the objects.
References
download from aws s3
aws policy, permission and roles
I want to protect my s3 object from Public access and the object can only be accessed from my origin. How can I do that? I tried by setting Objects Access control to Private, then Set in the buckets CORS settings, Allowed origin to my origin with the method GET but I'm getting an error while accessing the object.
How do I set the bucket to access the bucket objects only from my origin?
It sounds like you might be asking how to make an Amazon S3 bucket accessible to a specific Amazon CloudFront distribution.
From Restricting Access to Amazon S3 Content by Using an Origin Access Identity - Amazon CloudFront:
To restrict access to content that you serve from Amazon S3 buckets, follow these steps:
Create a special CloudFront user called an origin access identity (OAI) and associate it with your distribution.
Configure your S3 bucket permissions so that CloudFront can use the OAI to access the files in your bucket and serve them to your users. Make sure that users can’t use a direct URL to the S3 bucket to access a file there.
After you take these steps, users can only access your files through CloudFront, not directly from the S3 bucket.
I'm kinda new to AWS S3 - using EC2 (hosting web app) and S3 (storing resources) in the same AWS region, and assigned EC2 with an IAM role s3access, so EC2 can download from S3 easily.
The question is, how should a client download from S3? Apparently the client doesn't have IAM role or Access Key like EC2 does. Seems the client only have a signedDownloadUrl generated by aws-sdk, but it also requires access key.
So, should I make the bucket public then any client can download, or should I find some approach to supply the client with credentials?
All objects by default are private. Only the object owner has permission to access these objects.
So if you want to share an object with someone you can
You can make it public or
You, the object owner can share objects with others by creating a pre-signed URL, using their own security credentials, to grant time-limited permission to download the objects.
For more details on pre-signed URLs refer S3 Share Objects with PreSignedURL