title: Generate a Pre-signed URL Using the AWS SDK for Java
body: <p>I was following the example from <a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html" rel="nofollow noreferrer">https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html</a> to create pre-signed s3 urls (v4) and I get <strong>Access Denied</strong> error when I try to access the signed the url</p>
  
  <pre><code>&lt;Error&gt;
     &lt;Code&gt;AccessDenied&lt;/Code&gt;
     &lt;Message&gt;Access Denied&lt;/Message&gt;
     &lt;RequestId&gt;0FB02ECDDF5EAC7B&lt;/RequestId&gt;
     &lt;HostId&gt;vA+mmsv9PCunNe5uPkPrmpqqN3vFctQ13c9dIRlKWTYsT0zNA1V9g+4YS+lCItrBlyQtdHpyspg=&lt;/HostId&gt;
  &lt;/Error&gt;
  </code></pre>
  
  <p>The following is the code snippet</p>
  
  <pre><code>public class GeneratePresignedURL {
  
      public static void main(String[] args) throws IOException {
          String clientRegion = "us-east-1";
          String bucketName = "com-example-bucket";
          String objectKey = "path/to/file.img"; // No leading `/`
          // https://com-example-bucket.s3.amazonaws.com/path/to/file.img
  
          try { 
              AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain();
  
              // Assuming that us-east-1 defaults to v4, couldn't find a way to set it explicitly
              AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                      .withRegion(clientRegion)
                      .withCredentials(awsCredentialsProvider)
                      .build();
  
              // Set the presigned URL to expire after 10 minutes.
              java.util.Date expiration = new java.util.Date();
              long expTimeMillis = expiration.getTime();
              expTimeMillis += 1000 * 60 * 10;
              expiration.setTime(expTimeMillis);
  
              // Generate the presigned URL.
              System.out.println("Generating pre-signed 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());
              /*
                  sample signature:
                  https://com-example-bucket.s3.amazonaws.com/path/to/file.img?X-Amz-Security-Token=FQoDYXdzEDcaDLjUOdj2hDTZvWUQaiK3AxulqM%2BOPlp%2Bnq71P0LyuI0vj8tT%2F9i24Wd3jY8dUbudWbhUH9IAsPnl7asujO90GlaFP4dXujDDLwIakMjCJSfOFM4IoGJz8XtcjXkqJCNaenbrTA%2F3PfSl%2Fe9wQwJlY8gOu8%2Byioq2ElHULMKv52nEZj8s3v4dD0pGHQTYc4hGV7ty9CYwXNgz6w3TREhxuFdAewNgTRnY1uFNy7on6NDF5IE15vlJ2PxqrX53ZMLKP%2FdU8i5BcpZ3ySVhNpBpU3GJAPMOh%2B2ztCAk1zPjW4G0N5n9BlnjTMGs3vGBb9IW%2F8dzAoxaG9U9%2B%2FCp8euJN562dYYSZ9wmQgsfOVqc5OksdnHVkPJW400ObOcKmc9mqIRyqA%2B3Mv4z0%2Fx6iLYRJ3UaloFSGbmR6VlIxMl%2F67aHrmCnBE23a1%2BNMWgzLx%2FogqZy3CD%2F%2Fs6Jt1qkxUrRwC0RPK93LHD74qm8rjqZcEKFrBOrZsYtcl3zKgRIEHCbatQ7dwT634sdF0MwaD0vwTsbsStZDW903k5C%2FDuz4rEmkPv6c5CmFvxp4xOkUtMbDk4B8Z641CoeAMMOKICH%2FlW7%2F1as3nQo07Ow2QU%3D&amp;X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Date=20180621T214222Z&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Expires=3000&amp;X-Amz-Credential=&lt;access_key&gt;%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Signature=&lt;signature&gt;
              */
          }
          catch(AmazonServiceException e) {
              // The call was transmitted successfully, but Amazon S3 couldn't process 
              // it, so it returned an error response.
              e.printStackTrace();
          }
          catch(SdkClientException e) {
              // Amazon S3 couldn't be contacted for a response, or the client
              // couldn't parse the response from Amazon S3.
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>The signature format seems to be correct and I am not sure if I am missing some other s3 client config.
  Since I don't get a signature mismatch error or invalid url error, I assume that the Access Key used to sign the url is correct. </p>