Reputation: 6981
I've got an app that uploads documents to an S3 bucket. No problems there, but when I specify some custom headers in the request like so:
req.setHeader('x-amz-meta-purpose', 'purpose');
And write matching CORS rules for the bucket:
<CORSRule>
<AllowedOrigin>http://www.example.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<MaxAgeSeconds>3000</MaxAgeSec>
<ExposeHeader>x-amz-meta-purpose</ExposeHeader>
</CORSRule>
I get a 403 response. What am I forgetting? My code works fine without the custom header added.
Update
I get this response:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
How do I change my signature to include the custom header? It's currently made like this:
String stringToSign = 'PUT\n\n' + contentType + '\n' + now + '\n' + '/' + bucketname + '/' + lead.Id + '/' + fileName;
String encodedStringToSign = EncodingUtil.urlEncode(stringToSign, 'UTF-8');
Blob mac = Crypto.generateMac('HMACSHA1', Blob.valueOf(stringToSign), Blob.valueOf(secret));
String signed = EncodingUtil.base64Encode(mac);
Any ideas or documentation on how to add headers to that?
Upvotes: 0
Views: 406
Reputation: 179074
You are using Signature V2, so you need to include the "Canonicalized Amz Headers"...
String stringToSign = 'PUT\n\n' +
contentType + '\n' +
now + '\n' +
>>>>>> here >>>>>> CanonicalizedAmzHeaders +
'/' + bucketname + '/' + lead.Id + '/' + fileName;
Note there is no additional '\n' needed after this new value, but it the CanonicalizedAmzHeaders
string, itself, ends with a '\n'.
Canonicalized Amz headers is built by iterating through each header beginning with x-amz-
, with the header names converted to lowercase and then sorted lexically, building a string that looks like this (pseudocode):
lowercase(header1) + ':' + trim(value1) + '\n' +
lowercase(header2) + ':' + trim(value2) + '\n' +
...
So, in your request, it would the last three lines would look like this:
[date]\n
x-amz-meta-purpose:purpose\n
/bucketname/key
Upvotes: 1