Reputation: 205
I'm trying to create a signed URL for a GET object request in S3. I have this code working flawlessly for putting objects in S3 but I can't seem to get it to work for GET. I sign the URL with this code
//Create the signed url using the company id
func (user *User) signURLForUser(sess *session.Session) (*URLSign, error) {
svc := s3.New(sess)
svc.Config.Region = aws.String(os.Getenv("REGION"))
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String("bucket"),
Key: aws.String(user.CompanyID + "/" + user.FileRequest),
})
var urlSign URLSign
//urlSign.Size = *out.ContentLength
str, err := req.Presign(time.Minute * 60 * 24 * 5) //Expire in 5 days
if err != nil {
log.Println("Error signing URL Request")
return nil, err
}
urlSign.URL = str
return &urlSign, nil
}
But when I try to use the URL it returns I get this error:
<Error>
<Code>AuthorizationQueryParametersError</Code>
<Message>X-Amz-Algorithm only supports "AWS4-HMAC-SHA256"</Message>
<RequestId>9D7CFB14B195A260</RequestId>
<HostId>
Dgh+SqrHbrdKcbkCYrAj3nObLMAwS7k5+VR1zwC/8ZMS3S4++IAAEXXh3zMZ3CpOAyxX1Kc7Opg=
</HostId>
</Error>
I've check the IAM permissions, they're set for GetObject. I can't think of what else I'm doing wrong.
EDIT: Here's an example of the URL For sure: https://rsmachiner-user-code.s3.amazonaws.com//CFDMP_ServoGear.gcode?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=ASIAVEENPDKJRUDZKEVM%2F20180812%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180812T005443Z&X-Amz-Expires=432000&X-Amz-Security-Token=FQoGZXIvYXdzEBoaDIVdv9t408gWWi9vvSLjAaa0pZNA%2BXu83%2FFSyng4XvFdv5%2B7nRB%2FQydMLyi%2BBS84yXqwP6VYn7VlInw4ip1M0lkjHRXQf8OAvQLPrIl%2FQZoTe%2Fy3N6bqhLDOnFVJ3UZzYDQ4%2FbX%2Brc6mvVbkhRsQPiarKBuLYDiOD%2FNoSaItMwI9FsMDknw1qX0Pf%2BZ5La0GmanHrTt9YUI01cIUKJ40No5mKJIwcXw3%2F5QOpUc59rZ2zEzlWP9OXeEwWKp%2Bog5P0v7ABX1lRPsCx4HGEstKhw3ZWmJfQhAcAvhrjmXIMqGNKkaCI5L0ap23jf4GvPMGd4%2BcKIKKvtsF&X-Amz-SignedHeaders=host&X-Amz-Signature=82dfb9b392b5e1ef44c7140259ad884e696b48f8094bdd2d223b8650ebdf59f7
Upvotes: 4
Views: 8613
Reputation: 20052
I had the exact same issue when building a lambda and API Gateway integration in Go.
I used a custom JSON encoder and didn't realize it used HTML-escapes.
func jsonResponse(status int, body interface{}) APIGatewayResponse {
// Use a custom Encoder that disables HTML escaping -> this created the issue with \u2026 instead of the &
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false) // This is key to keep the pre-sign url working
if err := enc.Encode(body); err != nil {
return errorResponse(500, err.Error())
}
return APIGatewayResponse{
StatusCode: status,
Body: buf.String(),
Headers: map[string]string{"Content-Type": "application/json"},
}
}
I was embedding the \u0026–escaped JSON
as the raw string in the Body
initially. The client that made the request just saw the \u0026
instead of decoding the JSON again, which made the presigned URL malformed.
Upvotes: 0
Reputation: 161
Such issues occur when you are not correctly specifying the algorithm. For me, I was using this url: https://s3_endpoint?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026 which returned to me the same error. I replaced the \u0026 with & and it worked fine.
Upvotes: 15