Dear authors,
When using a generated url by Object_GetPreSignedUrl action for uploading file to S3 directly from PUT request in browser's JavaScript, AWS endpoint returned SignatureDoesNotMatch error.
The request signature we calculated does not match the signature you provided. Check your key and signing method.
After a while investigation, I revealed that the Object_GetPreSignedUrl action doesn't assume that request contains Content-Type header. I used the generated url in the terminal window with curl command no Content-Type header, then the PUT uploading completed without any errors.
On the other hand, when issuing PUT request from JavaScript of browser window, we have to use XMLHttpRequest class or fetch function. However these JavaScript functions can't remove Content-Type header from PUT request. So, using a generated url by Object_GetPreSignedUrl action will always result in a SignatureDoesNotMatch error.
To avoid the error, the Object_GetPreSignedUrl action must have an additional input parameter for Content-Type in order to direct PUT uploading from browser window. And the action have to use this parameter to generate url by AWS SDK.
[Generating presigned URL for browser PUT needs Content-Type | Stack Overflow]https://stackoverflow.com/a/41090784
[Content-Type is required for generating url for uploading | AWS SDK for .NET Documentation]https://docs.aws.amazon.com/sdkfornet1/latest/apidocs/html/P_Amazon_S3_Model_GetPreSignedUrlRequest_ContentType.htm
Sample oml is attached.
Could you please check my request?
Best regards, Moriya Takasi
Hi. I wrote an article about uploading large files to S3 from the browser using a presigned URL a while ago https://itnext.io/file-uploads-from-outsystems-reactive-web-client-to-aws-s3-using-pre-signed-urls-18e9a42dee17. There is also a sample component on forge with the article https://www.outsystems.com/forge/component-overview/14747/aws-s3-direct-file-upload-sample-o11. That components includes a reusable widget you can use and adapt to your own likings.
Looking at your module I would assume the problem is that you explicitly set the content-type when using XMLHttpRequest. You should be able to simply remove that to get it work, as if none is specified the octet-stream content type is implicitly assumed. (see my component).
But besides that the official S3 connector misses some vital functionality.
Stefan
Thank you for checking my sample oml, Stefan.
When I removed the line for an explicitly Content-Type header from my oml, the app will stil leads same error (I attached new oml).So, I think the forge should be implemented additional input parameter.
I will see your article and your forge.
Thanks again.
I ran Stefan's forge on my PE.
'success' message showed on browser screen. But the uploading was failed actually and the same error returned.
Hi Takasi. I was just rechecking my demo and it successfully uploads the document. However if found out that I do not have added proper error checking in case of a Forbidden error. Could you check the developer console if you get a 403 error (console error). Maybe you are just missing the proper IAM permissions to Generate a presigned Url. I suggest - for demo purposes - to add the S3Fullaccess policy to the IAM credentials you are using.
PS: We are using - a slightly modified version of this widget - in most of our customer environments. So it should work :-)
.... could it be that the filename (and therefor the S3 key) you try to upload contains Hiragana?
When the file name is 'test.png', the same error occurred.
I am using AmazonS3FullAccess policy.
And when using the generated url with curl command without Content-Type header, I can upload it to S3.So, it doesn't seem to be caused by IAM permission.
Thank you for your investigation.
Just posting my trace
But looking at this you are missing the region in the Host request header.
PS: When using the official S3 connector you have to provide the Region Enum value. For eu-central-1 this becomes "EUCentral1". Generating a presigned url is fully offline so if you enter a wrong value for the region it is just omitted.
Hi Stefan,
Sorry to be late.
I'm using 'USEast1' for specifying region. When I used 'us-east-1' by my mistake, generating URL failed. So, I think there is no error around specifying region.
And the host of endpoint URL generated doesn't contain region originally.I don't know why this lack. This may be because USEast1 is one of the initial AWS regions.
Using generated URL by curl command in the terminal window, uploading succeeded.
However, when appending Content-Type header with same command, uploading failed with SignatureDoesNotMatch error.
I can not remove Content-Type header from my request by XMLHttpRequest.And I found the next link as I wrote at first.So, I thought specifying Content-Type to generate presigned URL will lead a good result.
Thank you so match.
Seems like the useast1 region differs from eucentral1. I just set up a new bucket in the useast1 region and tried it. I now get the same error 403 with a signature mismatch. It still works in eucentral1.
But. I found a post an repost.aws https://repost.aws/questions/QU4N4twu_CSq2GgOkRj-lXEA/get-s3-presigned-url-signaturedoesnotmatch where someone is indicating that this could be a temporary issue. The author mentioned that he just waited a couple of days and then it succeeded. There is also a blog post https://brijendrasinghrajput.medium.com/signaturedoesnotmatch-aws-s3-solved-7a02d8578f29 mentioning that there are some temporary s3 issues which resolved over time. I would suggest to wait another one or two days to make sure it is not a temporary issue (however I never experienced something like this, but iam soley using the eucentral1 region)
Thank you for information.And thank you for reproducing the trouble on your site with useast1.
I'll wait a few days.
It's been more than a week since I first met the problem.I still get the same error when I use USEast1.And I confirmed that using EUCentral1 leads no error on my site same as Stefan wrote above.
I cloned the S3 connector forge and append an additional parameter for Content-Type to use PUT verb.When using the cloned component, uploading from browser to both USEast1 and EUCentral1 completed successfully.The cloned component is attached.
Revealed things:
So, I think that appending an additional parameter for PUT verb to official forge makes sense.
How do you think?