Skip to content

Upload document to S3 using PreSigned URL using AWS JDK 2.x not working #3005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
GusMCoutinho opened this issue Feb 1, 2022 · 6 comments
Closed
Assignees
Labels
closed-for-staleness guidance Question that needs advice or information.

Comments

@GusMCoutinho
Copy link

Describe the issue

I'm trying to upload a document to S3 bucket using presigned url that was generated using JDK 1.8 / AWS Java SDK 2.17.108, but I'm having the error "The request signature we calculated does not match the signature you provided. Check your key and signing method."

Steps to Reproduce

Following is the piece of code I have to generate the presigned URL:

log.info("Object Key: {}", objectKey);
            PutObjectRequest putObjectRequest =
                    PutObjectRequest.builder()
                            .acl(ObjectCannedACL.PUBLIC_READ_WRITE)
                            .bucket(bucket)
                            .key(objectKey)
                            .contentDisposition("attachment;filename=\"" + filename + "\"")
                            .contentType("text/plain")
                            .serverSideEncryption(ServerSideEncryption.AES256)
                            .overrideConfiguration(override)
                            .build();
            PutObjectPresignRequest putObjectPresignRequest =
                    PutObjectPresignRequest.builder()
                            .signatureDuration(duration)
                            .putObjectRequest(putObjectRequest)
                            .build();
            PresignedPutObjectRequest presignedPutObjectRequest =
                    s3Presigner.presignPutObject(putObjectPresignRequest);

Note: I'm also using IAM user access keys in the S3Presigner.builder method.

Current behavior

I'm having the below errors:
Error1
Error2

AWS Java SDK version used

2.17.108

JDK version used

1.8

Operating System and version

N/A

@GusMCoutinho GusMCoutinho added guidance Question that needs advice or information. needs-triage This issue or PR still needs to be triaged. labels Feb 1, 2022
@aaoswal aaoswal transferred this issue from aws/aws-sdk-java Feb 1, 2022
@debora-ito
Copy link
Member

@GusMCoutinho

Can you paste a generated URL in the comments? Please redact any sensitive information.

Presigned URLs work with query params to send values that would be usually sent by http headers.
The issue probably will be fixed if you add the acl, contentDisposition, contentType and serverSideEncryption as queryParams in the overrideConfiguration setting:

AwsRequestOverrideConfiguration override = AwsRequestOverrideConfiguration.builder()
    .putRawQueryParameter("x-amz-acl", "private")
    .putRawQueryParameter("x-amz-server-side-encryption", "AES256")
    .putRawQueryParameter("content-disposition", "attachment;filename=\"file.txt\"")
    .putRawQueryParameter("content-type", "text/plain")
    .build();

PutObjectRequest putObjectRequest = PutObjectRequest.builder()
    .bucket(BUCKET)
    .key(OBJECT)                        
    .overrideConfiguration(override)
    .build();

@debora-ito debora-ito added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 10 days. and removed needs-triage This issue or PR still needs to be triaged. labels Feb 2, 2022
@debora-ito debora-ito self-assigned this Feb 2, 2022
@GusMCoutinho
Copy link
Author

Hi @debora-ito ,

The suggestion you made helped, I'm now facing "Access Denied", although i have policies for the role being used by our microservice that allows all actions to our s3 bucket. Contacted AWS and they suggested that it could be a policy at organization level and we are investigating that now.

Thank you

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 10 days. label Feb 3, 2022
@GusMCoutinho
Copy link
Author

@debora-ito ,

Do you know if it is required to add additional parameter regarding encrypting to generate presigned url?

Note: The bucket where we want to upload documents uses KMS encryption (custom managed key created by us).

Thank you

@debora-ito
Copy link
Member

Yes, you need to add the parameters related to the server-side encryption you want to use.

One way to know which params to include is to execute a working PutObjectRequest with the required encryption settings, enable the verbose wirelogs (see instructions here) and check which x-amz-server-side-encryption-* headers are sent in the request. The same headers need to be added as query params to the presigned URL.

@debora-ito debora-ito added the closing-soon This issue will close in 4 days unless further comments are made. label Feb 3, 2022
@github-actions github-actions bot added closed-for-staleness and removed closing-soon This issue will close in 4 days unless further comments are made. labels Feb 6, 2022
@github-actions github-actions bot closed this as completed Feb 6, 2022
@rizthetechie
Copy link

Amazon really need to get their documents right, so many people facing this issue. No where on their document i could find the solution to this

@bubaigit
Copy link

bubaigit commented Jan 16, 2025

Hi I am using AWS SDK - 2x with below POM configuration. The Preassigned URL code we use - will successfully generated the link but when we click the Link - it will show below error -

<Code>SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message> <AWSAccessKeyId>ASIAWHB6CBAUK5XMNCDB</AWSAccessKeyId> <StringToSign>AWS4-HMAC-SHA256 20250116T062638Z 20250116/us-east-2/s3/aws4_request 042b6840c5545b903f3c841ff36d04d4354dd883e03e49c2b50752d343101e81</StringToSign> <SignatureProvided>575e902f666f969baff2b4dcd0a16420f1bf7d18597224c839741ce13cdfa8d9</SignatureProvided>

we will use - software.amazon.awssdk version - 2.20.0 / spring-boot-starter-parent - 3.3.7 / JDK 21

POM File

Image Image Image

pom.txt

Bucket Setting

Tried with Content-Type for the bucket CORS setting and
*

The Java code

`
public String generatePreSignedUrl(String bucketname, String fileKey, S3Client s3Client) {

	LOGGER.info("bucketname and fileKey: {} {}", bucketname, fileKey);
	
           String downloadUrl = null;

	AwsRequestOverrideConfiguration override = AwsRequestOverrideConfiguration
			.builder()
			.putRawQueryParameter("x-amz-acl", "private")
			.putRawQueryParameter("x-amz-server-side-encryption", "AES256")
			.putRawQueryParameter("content-disposition", "attachment;filename=\"file.zip\"")
			.putRawQueryParameter("content-type", "application/zip")
			.build();

	S3Presigner presigner = S3Presigner.builder()
			.region(Region.US_EAST_2) // Specify the region
			.credentialsProvider(DefaultCredentialsProvider.create())
			.build();

	GetObjectRequest getObjectRequest = GetObjectRequest.builder()
			.bucket(bucketname) // Replace with the bucket name
			.key(fileKey) // Replace with the object key
			.overrideConfiguration(override)   // we tried with or without 
			.build();

	GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
			.getObjectRequest(getObjectRequest)
			.signatureDuration(Duration.ofDays(5)) // Set duration for 5 days
			.build();

	PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);

	
	downloadUrl = presignedRequest.url().toString();

	presigner.close();

	
	return downloadUrl;
}

`

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-for-staleness guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

4 participants