Reputation: 11
I am trying to upload a test PDF file and generate a presigned URL using GetPreSignedUrlRequest
but getting following error while try to access the presigned URL:
<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>xxxxxxxxxxxxxxxxxxxxxxx</AWSAccessKeyId>
<StringToSign>GET 1607367406 /TESTBUCKET/TEST.pdf</StringToSign>
<SignatureProvided>qMFjJ+j0wDtXKUjWW3jGQSktEMA=</SignatureProvided>
<StringToSignBytes> 47 45 54 0a 0a 0a 31 36 30 37 33 36 37 34 30 36 0a 2f 65 61 64 63 74 64 62 75 63 6b 65 74 72 65 70 6f 72 74 2f 63 72 6f 73 73 70 61 74 69 65 6e 74 2e 70 64 66</StringToSignBytes>
<RequestId>9FE8E72C7C436320</RequestId>
<HostId>4z49ibT2YqJxGz436pEtuSnV4L2chzy+vmsKtAbGZBJS+We39yquFwYS+5Wd98sdtrsnBBb9YHg=</HostId>
</Error>
My code:
public HttpWebResponse UploadObject(string filePath, string url)
{
HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest;
httpRequest.Method = "PUT";
using (Stream dataStream = httpRequest.GetRequestStream())
{
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[fileStream.Length];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
dataStream.Write(buffer, 0, bytesRead);
}
}
}
return httpRequest.GetResponse() as HttpWebResponse;
}
public string GeneratePreSignedURL(string key)
{
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
BucketName = _bucket,
Key = key,
Verb = HttpVerb.PUT,
Expires = DateTime.Now.AddYears(5)
};
return client.GetPreSignedURL(request);
}
Consumer:
public void UploadValidPdfObject()
{
string applicationName = ConfigurationManager.AppSettings["ApplicationName"];
string s3ReportBucket = ConfigurationManager.AppSettings["S3ReportBucketName"];
byte[] result = File.ReadAllBytes(@"c:\test.pdf");
string fileKey = DateTime.UtcNow.Ticks.ToString();
string fileName = fileKey + ".pdf";
string fileNameResult = fileKey + "1.pdf";
string filePath = GetCurrentExeLoccation() + fileName;
//SET CloudStoreType.AmazonS3Direct, s3ReportBucket, applicationName
string preSignedURL = GeneratePreSignedURL(fileKey + ".pdf");
File.WriteAllBytes(filePath, result);
UploadObject(filePath, preSignedURL);
if (preSignedURL != null)
{
string resultFilePath = GetCurrentExeLoccation() + fileNameResult;
WebClient webClient = new WebClient();
webClient.DownloadFile(preSignedURL, GetCurrentExeLoccation() + resultFilePath);
Assert.IsTrue(File.Exists(resultFilePath));
File.Delete(filePath);
File.Delete(resultFilePath);
}
}
Upvotes: 1
Views: 693
Reputation: 178956
The error response indicates that you are trying to GET
an object... but your code in GeneratePreSignedURL()
appears to generate a pre-signed URL for a PUT
request. Uploading and downloading the same file requires a different signature for each operation, because the http verb is part of the string to sign, thus changing the signature when the verb changes, even if nothing else does.
Upvotes: 2