Reputation: 1594
I am using AWS S3 to store photos in conversations between users in my chat application (backend is written in Java / Spring Boot). At the moment, access to the bucket is public, which means that every user who would guesses the url will be able to see the picture.
What I would like to achieve is to restrict access to the resource only to interlocutors who belong to the given conversation so that they can see the photos sent between them.
I don't want to run all the traffic through my backend, I just want to delegate authorization to the S3. Is it possible to set some kind of "auth token" to restrict access to the given object on s3? I would generate this token on my backend and possibly refresh it from time to time. Are there any other recommended options for this task?
Upvotes: 1
Views: 181
Reputation: 17495
As indicated, you can presign the URL. In Java (API V1) the basics are something like:
String bucketName = "the-bucket-name";
String objectKey = "/your/object/keyname.jpg";
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
// Set the presigned URL to expire after one hour.
Date expiration = new Date();
long expTimeMillis = expiration.getTime() + 1000 * 60 * 60;
expiration.setTime(expTimeMillis);
// Generate the presigned URL.
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucketName, objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(expiration);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
System.out.println("Pre-Signed URL: " + url.toString());
This allows anyone to access the image for one hour if they have the URL. Presumably you could generate the URL to include on a web page and the likelihood of sharing the link is low.
If you must have a guarantee that only the correct person can access the image then you'll need some sort of server side component. You can route it through your server or possibly a API Gateway/Lambda component.
Upvotes: 3
Reputation: 929
You can create presigned URLs for S3 objects. This generates a temporary link that grants access to an S3 object, even if the bucket is not public.
As an example/test, you could run the aws s3 presign
command in the AWS CLI:
aws s3 presign s3://BucketName/SomePhoto.png --expires-in 86400
This command will return an address that can be used to access SomePhoto.png
. The URL will be valid for 86400
seconds, which is one day. --expires-in
is optional.
More details on the command lind reference can be found here.
Upvotes: 2