Interface S3Presigner

All Superinterfaces:
AutoCloseable, SdkAutoCloseable, SdkPresigner
All Known Implementing Classes:
DefaultS3Presigner

@Immutable @ThreadSafe public interface S3Presigner extends SdkPresigner
Enables signing an S3 SdkRequest so that it can be executed without requiring any additional authentication on the part of the caller.

For example: if Alice has access to an S3 object, and she wants to temporarily share access to that object with Bob, she can generate a pre-signed GetObjectRequest to secure share with Bob so that he can download the object without requiring access to Alice's credentials.

Signature Duration

Pre-signed requests are only valid for a finite period of time, referred to as the signature duration. This signature duration is configured when the request is generated, and cannot be longer than 7 days. Attempting to generate a signature longer than 7 days in the future will fail at generation time. Attempting to use a pre-signed request after the signature duration has passed will result in an access denied response from the service. For S3Express requests, the signature duration cannot be longer than 5 minutes. This is due to S3Express credentials having a short lifespan of only 5 minutes.

Example Usage

 
     // Create an S3Presigner using the default region and credentials.
     // This is usually done at application startup, because creating a presigner can be expensive.
     S3Presigner presigner = S3Presigner.create();

     // Create a GetObjectRequest to be pre-signed
     GetObjectRequest getObjectRequest =
             GetObjectRequest.builder()
                             .bucket("my-bucket")
                             .key("my-key")
                             .build();

     // Create a GetObjectPresignRequest to specify the signature duration
     GetObjectPresignRequest getObjectPresignRequest =
         GetObjectPresignRequest.builder()
                                .signatureDuration(Duration.ofMinutes(10))
                                .getObjectRequest(getObjectRequest)
                                .build();

     // Generate the presigned request
     PresignedGetObjectRequest presignedGetObjectRequest =
         presigner.presignGetObject(getObjectPresignRequest);

     // Log the presigned URL, for example.
     System.out.println("Presigned URL: " + presignedGetObjectRequest.url());

     // It is recommended to close the S3Presigner when it is done being used, because some credential
     // providers (e.g. if your AWS profile is configured to assume an STS role) require system resources
     // that need to be freed. If you are using one S3Presigner per application (as recommended), this
     // usually is not needed.
     presigner.close();
 
 

Browser Compatibility

Some pre-signed requests can be executed by a web browser. These "browser compatible" pre-signed requests do not require the customer to send anything other than a "host" header when performing an HTTP GET against the pre-signed URL. For S3Express requests, an additional "x-amz-s3session-token" header will be included.

Whether a pre-signed request is "browser compatible" can be determined by checking the PresignedRequest.isBrowserExecutable() flag. It is recommended to always check this flag when the pre-signed request needs to be executed by a browser, because some request fields will result in the pre-signed request not being browser-compatible.

Configurations that affect browser compatibility

Enabling Checking Validation

If checksum validations are enabled, the presigned URL will no longer be browser compatible because it adds a signed header that must be included in the HTTP request. Checksum validation is disabled in the presigner by default, but when using a custom S3Configuration when enabling features like path style access or accelerate mode, it must be explicitly disabled:
         S3Presigner presigner = S3Presigner.builder()
                                            .serviceConfiguration(S3Configuration.builder()
                                                                                 .checksumValidationEnabled(false)
                                                                                 .build())
                                            .build();
 

Executing a Pre-Signed Request from Java code

Browser-compatible requests (see above) can be executed using a web browser. All pre-signed requests can be executed from Java code. This documentation describes two methods for executing a pre-signed request: (1) using the JDK's URLConnection class, (2) using an SDK synchronous SdkHttpClient class.

Using {code URLConnection}:

     // Create a pre-signed request using one of the "presign" methods on S3Presigner
     PresignedRequest presignedRequest = ...;

     // Create a JDK HttpURLConnection for communicating with S3
     HttpURLConnection connection = (HttpURLConnection) presignedRequest.url().openConnection();

     // Specify any headers that are needed by the service (not needed when isBrowserExecutable is true)
     presignedRequest.httpRequest().headers().forEach((header, values) -> {
         values.forEach(value -> {
             connection.addRequestProperty(header, value);
         });
     });

     // Send any request payload that is needed by the service (not needed when isBrowserExecutable is true)
     if (presignedRequest.signedPayload().isPresent()) {
         connection.setDoOutput(true);
         try (InputStream signedPayload = presignedRequest.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);
     }
 

Using {code SdkHttpClient}:

     // Create a pre-signed request using one of the "presign" methods on S3Presigner
     PresignedRequest presignedRequest = ...;

     // Create an SdkHttpClient using one of the implementations provided by the SDK
     SdkHttpClient httpClient = ApacheHttpClient.builder().build(); // or UrlConnectionHttpClient.create()

     // Specify any request payload that is needed by the service (not needed when isBrowserExecutable is true)
     ContentStreamProvider requestPayload =
         presignedRequest.signedPayload()
                         .map(SdkBytes::asContentStreamProvider)
                         .orElse(null);

     // Create the request for sending to the service
     HttpExecuteRequest request =
         HttpExecuteRequest.builder()
                           .request(presignedRequest.httpRequest())
                           .contentStreamProvider(requestPayload)
                           .build();

     // Call the service
     HttpExecuteResponse response = httpClient.prepareRequest(request).call();

     // Download the result of executing the request
     if (response.responseBody().isPresent()) {
         try (InputStream responseStream = response.responseBody().get()) {
             System.out.println("Service returned response: ");
             IoUtils.copy(content, System.out);
         }
     }
 

S3Express

When pre-signing S3Express requests, no special configuration is required if you want to presign using regular IAM / Sigv4 credentials, which are more long-lived than S3 express session credentials. In order to presign using S3 express session credentials, you must provide an S3Client that can make the extra call to S3 in order to fetch them. For more information, see S3Presigner.Builder.s3Client(S3Client) and S3Presigner.Builder.disableS3ExpressSessionAuth(Boolean). The latter option can be used to explicitly disable session auth.

Example Usage

 

    //Create a standard S3Presigner that will presign S3 express bucket requests with Sigv4 credentials
    S3Presigner presigner = S3Presigner.builder()
                                       .build();

    //Create an S3Presigner that will presign S3 express bucket requests with session credentials
    S3Presigner presigner = S3Presigner.builder()
                                       .s3Client(s3Client)
                                       .build();

    //Create an S3Presigner that explicitly disallows presigning S3 express bucket requests with session credentials
    S3Presigner presigner = S3Presigner.builder()
                                       .disableS3ExpressSessionAuth(true)
                                       .build();
 
 
  • Method Details

    • create

      static S3Presigner create()
      Create an S3Presigner with default configuration. The region will be loaded from the DefaultAwsRegionProviderChain and credentials will be loaded from the DefaultCredentialsProvider.

      This is usually done at application startup, because creating a presigner can be expensive. It is recommended to SdkPresigner.close() the S3Presigner when it is done being used.

    • builder

      static S3Presigner.Builder builder()
      Create an S3Presigner.Builder that can be used to configure and create a S3Presigner.

      This is usually done at application startup, because creating a presigner can be expensive. It is recommended to SdkPresigner.close() the S3Presigner when it is done being used.

    • presignGetObject

      Presign a GetObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Create a GetObjectRequest to be pre-signed
           GetObjectRequest getObjectRequest = ...;
      
           // Create a GetObjectPresignRequest to specify the signature duration
           GetObjectPresignRequest getObjectPresignRequest =
               GetObjectPresignRequest.builder()
                                      .signatureDuration(Duration.ofMinutes(10))
                                      .getObjectRequest(request)
                                      .build();
      
           // Generate the presigned request
           PresignedGetObjectRequest presignedGetObjectRequest =
               presigner.presignGetObject(getObjectPresignRequest);
      
           if (presignedGetObjectRequest.isBrowserExecutable())
               System.out.println("The pre-signed request can be executed using a web browser by " +
                                  "visiting the following URL: " + presignedGetObjectRequest.url());
           else
               System.out.println("The pre-signed request has an HTTP method, headers or a payload " +
                                  "that prohibits it from being executed by a web browser. See the S3Presigner " +
                                  "class-level documentation for an example of how to execute this pre-signed " +
                                  "request from Java code.");
       
       
    • presignGetObject

      Presign a GetObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignGetObject(GetObjectPresignRequest) without needing to call GetObjectPresignRequest.builder() or .build().

      See Also:
    • presignPutObject

      Presign a PutObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Create a PutObjectRequest to be pre-signed
           PutObjectRequest putObjectRequest = ...;
      
           // Create a PutObjectPresignRequest to specify the signature duration
           PutObjectPresignRequest putObjectPresignRequest =
               PutObjectPresignRequest.builder()
                                      .signatureDuration(Duration.ofMinutes(10))
                                      .putObjectRequest(request)
                                      .build();
      
           // Generate the presigned request
           PresignedPutObjectRequest presignedPutObjectRequest =
               presigner.presignPutObject(putObjectPresignRequest);
       
       
    • presignPutObject

      Presign a PutObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignPutObject(PutObjectPresignRequest) without needing to call PutObjectPresignRequest.builder() or .build().

      See Also:
    • presignDeleteObject

      Presign a DeleteObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Create a DeleteObjectRequest to be pre-signed
           DeleteObjectRequest deleteObjectRequest = ...;
      
           // Create a PutObjectPresignRequest to specify the signature duration
           DeleteObjectPresignRequest deleteObjectPresignRequest =
               DeleteObjectPresignRequest.builder()
                                         .signatureDuration(Duration.ofMinutes(10))
                                         .deleteObjectRequest(deleteObjectRequest)
                                         .build();
      
           // Generate the presigned request
           PresignedDeleteObjectRequest presignedDeleteObjectRequest =
               presigner.presignDeleteObject(deleteObjectPresignRequest);
       
       
    • presignDeleteObject

      Presign a DeleteObjectRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignDeleteObject(DeleteObjectPresignRequest) without needing to call DeleteObjectPresignRequest.builder() or .build().

      See Also:
      • invalid reference
        #presignDeleteObject(PresignedDeleteObjectRequest)
    • presignCreateMultipartUpload

      Presign a CreateMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Create a CreateMultipartUploadRequest to be pre-signed
           CreateMultipartUploadRequest createMultipartUploadRequest = ...;
      
           // Create a CreateMultipartUploadPresignRequest to specify the signature duration
           CreateMultipartUploadPresignRequest createMultipartUploadPresignRequest =
               CreateMultipartUploadPresignRequest.builder()
                                                  .signatureDuration(Duration.ofMinutes(10))
                                                  .createMultipartUploadRequest(request)
                                                  .build();
      
           // Generate the presigned request
           PresignedCreateMultipartUploadRequest presignedCreateMultipartUploadRequest =
               presigner.presignCreateMultipartUpload(createMultipartUploadPresignRequest);
       
       
    • presignCreateMultipartUpload

      Presign a CreateMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignCreateMultipartUpload(CreateMultipartUploadPresignRequest) without needing to call CreateMultipartUploadPresignRequest.builder() or .build().

      See Also:
    • presignUploadPart

      Presign a UploadPartRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Create a UploadPartRequest to be pre-signed
           UploadPartRequest uploadPartRequest = ...;
      
           // Create a UploadPartPresignRequest to specify the signature duration
           UploadPartPresignRequest uploadPartPresignRequest =
               UploadPartPresignRequest.builder()
                                       .signatureDuration(Duration.ofMinutes(10))
                                       .uploadPartRequest(request)
                                       .build();
      
           // Generate the presigned request
           PresignedUploadPartRequest presignedUploadPartRequest =
               presigner.presignUploadPart(uploadPartPresignRequest);
       
       
    • presignUploadPart

      Presign a UploadPartRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignUploadPart(UploadPartPresignRequest) without needing to call UploadPartPresignRequest.builder() or .build().

      See Also:
    • presignCompleteMultipartUpload

      Presign a CompleteMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Complete a CompleteMultipartUploadRequest to be pre-signed
           CompleteMultipartUploadRequest completeMultipartUploadRequest = ...;
      
           // Create a CompleteMultipartUploadPresignRequest to specify the signature duration
           CompleteMultipartUploadPresignRequest completeMultipartUploadPresignRequest =
               CompleteMultipartUploadPresignRequest.builder()
                                                    .signatureDuration(Duration.ofMinutes(10))
                                                    .completeMultipartUploadRequest(request)
                                                    .build();
      
           // Generate the presigned request
           PresignedCompleteMultipartUploadRequest presignedCompleteMultipartUploadRequest =
               presigner.presignCompleteMultipartUpload(completeMultipartUploadPresignRequest);
       
       
    • presignCompleteMultipartUpload

      Presign a CompleteMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignCompleteMultipartUpload(CompleteMultipartUploadPresignRequest) without needing to call CompleteMultipartUploadPresignRequest.builder() or .build().

      See Also:
    • presignAbortMultipartUpload

      Presign a AbortMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      Example Usage

       
           S3Presigner presigner = ...;
      
           // Complete a AbortMultipartUploadRequest to be pre-signed
           AbortMultipartUploadRequest abortMultipartUploadRequest = ...;
      
           // Create a AbortMultipartUploadPresignRequest to specify the signature duration
           AbortMultipartUploadPresignRequest abortMultipartUploadPresignRequest =
               AbortMultipartUploadPresignRequest.builder()
                                                    .signatureDuration(Duration.ofMinutes(10))
                                                    .abortMultipartUploadRequest(request)
                                                    .build();
      
           // Generate the presigned request
           PresignedAbortMultipartUploadRequest presignedAbortMultipartUploadRequest =
               presigner.presignAbortMultipartUpload(abortMultipartUploadPresignRequest);
       
       
    • presignAbortMultipartUpload

      Presign a AbortMultipartUploadRequest so that it can be executed at a later time without requiring additional signing or authentication.

      This is a shorter method of invoking presignAbortMultipartUpload(AbortMultipartUploadPresignRequest) without needing to call AbortMultipartUploadPresignRequest.builder() or .build().

      See Also: