How to allow CloudFront to access certain S3? - amazon-web-services

I'm new to AWS. Now I want to write a java code to use CloudFront to access a s3.
I create a S3 bucket. But I don't know how to get cloudfront object using S3 credentials.
I read the AWS JAVA API, it seems that the code should be in this form:
AmazonCloudFrontClient cloudfront = new AmazonCloudFrontClient(credentials);
CreateCloudFrontOriginAccessIdentityRequest originRequest = new CreateCloudFrontOriginAccessIdentityRequest();
originRequest.setRequestCredentials(credentials);
cloudfront.createCloudFrontOriginAccessIdentity(originRequest);
But I don't see a S3ID or something to set the S3 to the cloudfront.

If you want to serve your S3 files with CloudFront, it usually means that you want the S3 bucket to be publicly available. You can simply define your objects and bucket as public though S3 interfaces (Web console, API, or 3rd party tools as CloudBerry or Bucket Explorer).
You can also set it with the Java SDK
Statement allowPublicReadStatement = new Statement(Effect.Allow)
.withPrincipals(Principal.AllUsers)
.withActions(S3Actions.GetObject)
.withResources(new S3ObjectResource(myBucketName, "*"));
Policy policy = new Policy()
.withStatements(allowPublicReadStatement);
AmazonS3 s3 = new AmazonS3Client(myAwsCredentials);
s3.setBucketPolicy(myBucketName, policy.toJson());
If you want to serve private files, you can check the documentations here: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

Related

Allow S3 hosted App exclusive permission to upload files to public bucket

I have a static React App I have deployed using Cloudfront - hosted within an S3 Bucket. I would like the user to have the option to upload files in the future, through this app, to the bucket but I am a little confused on the permissions side.
I have created the Bucket with the CDK like so...
val siteBucket = Bucket(
this, "SiteBucket",
BucketProps.builder()
.bucketName(SITE_DOMAIN_NAME)
.websiteIndexDocument("index.html")
.publicReadAccess(true)
.removalPolicy(DESTROY)
.build()
)
I have additional config using the CDK to hook up the CloudFrontWebDistribution and to route the traffic to my domain.
My understanding of the above is that .publicReadAccess(true) allows my Bucket to be accessible to the wider internet - but that it doesn't grant any rights to upload to the bucket.
However, how do I use the CDK to grant permissions for only my static webapp to upload to the Bucket - but not for anyone else to upload?
(I've been reviewing this https://docs.aws.amazon.com/cdk/v2/guide/permissions.html but unsure of the best practise e.g. can my app have a role or permissions assigned to when the app itself is just the contents of a bucket. Do I need to create an Access Point? But again, how do I limit my app to have permissions - is this even possible with a static app or do I need a backend/Lambda to invoke first?)
Thanks!
For one, you don't need publicReadAccess. You can just grant access to the OAI.
https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/
This is a pretty good starting point for the page though:
https://aws.amazon.com/blogs/storage/allowing-external-users-to-securely-and-directly-upload-files-to-amazon-s3/
Not sure you necessarily want to use the same bucket to upload to and host your site.

Adding a response header to S3 bucket calls

I have a s3 bucket that I created and I am adding objects and reading them in a client that calls the bucket via my_bucket.s3.ap-southeast-2.amazonaws.com endpoint. Is there any way to add a header (eg: Strict-Transport-Security) to the responses from S3 (using aws console or cloudformation).
I am aware that I can do this by using cloudfront to route the request. But I want to know if I can achieve this directly from S3.

Should my bucket be public for my usecase and how should I avoid bad practice?

I'm new to AWS tools and although I have tried to search thoroughly for an answer I wasn't able to fixate on a solution.
My usecase is this:
I have a bucket where I need to store images, upload them via my server however I need to display them on my website.
Should my bucket be public?
If not, what should I do to allow everyone to read those images but not be able to mass upload on it from origins who are not my server?
If you want the images to be publicly accessible for your website, then the objects need to be public.
This can be done by creating a Bucket Policy that makes the whole bucket, or part of the bucket, publicly accessible.
Alternatively, when uploading the images, you can use ACL='public-read', which makes the individual objects public even if the bucket isn't public. This way, you can have more fine-grained control over what content in the bucket is public.
Both of these options require you to turn off portions of S3 Block Public Access to allow the Bucket Policy or ACLs.
When your server uploads to S3, it should be using Amazon S3 API calls using a set of AWS credentials (Access Key, Secret Key) from an IAM User. Grant the IAM User permission to put objects in the bucket. This way, that software can upload to the bucket totally independently to whether the bucket is public. (Never make a bucket publicly writable/uploadable, otherwise people can store anything in there without your control.)
upload them via my server however I need to display them on my website.
In that case only your server can upload the images. So if you are hosting your web app on EC2 or ECS, then you use instance role and task role to provide S3 write access.
Should my bucket be public?
It does not have to. Often CloudFront is used to host images or files from S3 using OAI. This way your bucket remains fully private.

How to block public access on S3 bucket while allowing my rest API and mobile apps to access the files

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.

Why are static files from AWS S3 not loading?

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