You can now use the Amazon S3 Transfer Manager (Developer Preview)
Working with Amazon S3 presigned URLs
You can use a
S3Presigner
object to sign an Amazon S3
SdkRequest
so that it’s executed without requiring authentication on
the part of the caller. For example, assume Alice has access to an S3 object, and she wants to
temporarily share access to that object with Bob. Alice can generate a pre-signed
GetObjectRequest
object to secure share with Bob so that he can download the object without requiring access to
Alice’s credentials.
Generate a Presigned URL and Upload an Object
Build a
S3Presigner
object that represents the client object. Next create a
PresignedPutObjectRequest
object that can be executed at a later time without requiring additional signing or
authentication. When you create this object, you can specify the bucket name and the key name. In
addition, you can also specify the time in minutes that the bucket can be accessed without using
credentials by invoking the signatureDuration
method (as shown in the following code example).
You can use the
PresignedPutObjectRequest
object to obtain the URL by invoking its url
method.
Imports
import java.io.IOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.time.Duration; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
Code
The following Java code example uploads content to a presigned S3 bucket.
public static void signBucket(S3Presigner presigner, String bucketName, String keyName) { try { PutObjectRequest objectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(keyName) .contentType("text/plain") .build(); PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder() .signatureDuration(Duration.ofMinutes(10)) .putObjectRequest(objectRequest) .build(); PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest); String myURL = presignedRequest.url().toString(); System.out.println("Presigned URL to upload a file to: " +myURL); System.out.println("Which HTTP method needs to be used when uploading a file: " + presignedRequest.httpRequest().method()); // Upload content to the Amazon S3 bucket by using this URL URL url = presignedRequest.url(); // Create the connection and use it to upload the new object by using the presigned URL HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type","text/plain"); connection.setRequestMethod("PUT"); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream()); out.write("This text was uploaded as an object by using a presigned URL."); out.close(); connection.getResponseCode(); System.out.println("HTTP response code is " + connection.getResponseCode()); } catch (S3Exception e) { e.getStackTrace(); } catch (IOException e) { e.getStackTrace(); } }
See the
complete example
Get a Presigned Object
Build a
S3Presigner
object that represents the client object. Next, create a
GetObjectRequest
object and specify the bucket name and key name. In addition, create a
GetObjectPresignRequest
object that can be executed at a later time without requiring additional signing or
authentication. When you create this object, you can specify the time in minutes that the bucket
can be accessed without using credentials by invoking the signatureDuration
method (as shown in
the following code example).
Invoke the presignGetObject
method that belongs to the
S3Presigner
object to create a
PresignedPutObjectRequest
object. You can invoke this object’s url
method to obtain the URL to use. Once you have the
URL, you can use standard HTTP Java logic to read the contents of the bucket, as shown in the
following Java code example.
Imports
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.time.Duration; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.utils.IoUtils;
Code
The following Java code example reads content from a presigned S3 bucket.
public static void getPresignedUrl(S3Presigner presigner, String bucketName, String keyName ) { try { GetObjectRequest getObjectRequest = GetObjectRequest.builder() .bucket(bucketName) .key(keyName) .build(); GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder() .signatureDuration(Duration.ofMinutes(10)) .getObjectRequest(getObjectRequest) .build(); // Generate the presigned request PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest); // Log the presigned URL System.out.println("Presigned URL: " + presignedGetObjectRequest.url()); HttpURLConnection connection = (HttpURLConnection) presignedGetObjectRequest.url().openConnection(); presignedGetObjectRequest.httpRequest().headers().forEach((header, values) -> { values.forEach(value -> { connection.addRequestProperty(header, value); }); }); // Send any request payload that the service needs (not needed when isBrowserExecutable is true) if (presignedGetObjectRequest.signedPayload().isPresent()) { connection.setDoOutput(true); try (InputStream signedPayload = presignedGetObjectRequest.signedPayload().get().asInputStream(); OutputStream httpOutputStream = connection.getOutputStream()) { IoUtils.copy(signedPayload, httpOutputStream); } } // Download the result of executing the request try (InputStream content = connection.getInputStream()) { System.out.println("Service returned response: "); IoUtils.copy(content, System.out); } } catch (S3Exception e) { e.getStackTrace(); } catch (IOException e) { e.getStackTrace(); } }
See the
complete example