Description
Describe the bug
When upgrading to github.com/aws/aws-sdk-go-v2 v1.24.1 I am getting a SignatureDoesNotMatch
error when doing a PUT on a presigned url.
Expected Behavior
No errors when PUT request to presingned url
Current Behavior
When I make the PUT request to the presigned url this is the error:
<?xml version="1.0" encoding="UTF-8"?>
<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>[REDACTED]</AWSAccessKeyId>
<StringToSign>[REDACTED]</StringToSign>
<SignatureProvided>[REDACTED]</SignatureProvided>
<StringToSignBytes>[REDACTED]</StringToSignBytes>
<CanonicalRequest>PUT [REDACTED]</CanonicalRequest>
<CanonicalRequestBytes>[REDACTED]</CanonicalRequestBytes>
<RequestId>[REDACTED]</RequestId>
<HostId>[REDACTED]</HostId>
</Error>
Reproduction Steps
Generate presigned URL:
func (p Presigner) PutObject(
ctx context.Context,
objectKey string,
lifetimeSecs int64,
) (*v4.PresignedHTTPRequest, error) {
return p.PresignClient.PresignPutObject(
ctx,
&s3.PutObjectInput{
Bucket: aws.String(string(p.BucketName)),
Key: aws.String(objectKey),
},
s3.WithPresignExpires(time.Duration(lifetimeSecs*int64(time.Second))),
)
}
Make a request to the presigned URL generated.
Possible Solution
I have been debugging and I think the error is introduced in this commit.
Now when the presigned url is generated it goes through this middleware github.com/aws/[email protected]/aws/retry/middleware.go:286 that adds this header Amz-Sdk-Request
:
const retryMetricHeader = "Amz-Sdk-Request"
switch req := in.Request.(type) {
case *http.Request:
req.Header[retryMetricHeader] = append(req.Header[retryMetricHeader][:0], strings.Join(parts, "; "))
default:
return out, metadata, fmt.Errorf("unknown transport type %T", req)
}
And this causes the url to be generated with this &X-Amz-SignedHeaders=amz-sdk-request;host
in aws/[email protected]/aws/signer/v4/v4.go:185 on signedHeadersStr = amz-sdk-request;host
signedHeaders, signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(host, v4Internal.IgnoredHeaders, unsignedHeaders, s.Request.ContentLength)
With github.com/aws/aws-sdk-go-v2 v1.24.0 signedHeadersStr = host
If I exclude the header Amz-Sdk-Request
at github.com/aws/[email protected]/aws/signer/internal/v4/headers.go:4
// IgnoredHeaders is a list of headers that are ignored during signing
var IgnoredHeaders = Rules{
ExcludeList{
MapRule{
"Authorization": struct{}{},
"User-Agent": struct{}{},
"X-Amzn-Trace-Id": struct{}{},
"Expect": struct{}{},
"Amz-Sdk-Request": struct{}{},
},
},
}
The url is generated correctly and works.
I don't have much context and I don't know if the solution is to simply add the header to IgnoredHeaders
or if it shouldn't go through that Middleware.
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
github.com/aws/aws-sdk-go-v2 v1.24.1
Compiler and Version used
go version go1.21.1 darwin/arm64
Operating System and version
macOS Ventura 13.4
Activity