2015-12-07 38 views
1

我想上傳一個測試的PDF文件,並生成使用GetPreSignedUrlRequest一個presigned URL,但得到以下錯誤而嘗試訪問presigned網址:GetPreSignedUrlRequest - SignatureDoesNotMatch

<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> 

我的代碼:

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); 
} 

消費者:

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); 
    }   
} 

回答

1

錯誤響應表明您正在嘗試使用GET對象...但您的GeneratePreSignedURL()中的代碼似乎會爲PUT請求生成預先簽名的網址。上傳和下載相同的文件需要每個操作的不同簽名,因爲http動詞是要簽名的字符串的一部分,從而在動詞變化時更改簽名,即使沒有其他操作。

+0

謝謝。就是這樣... – BDotNet

+0

太棒了。請點擊複選標記將答案標記爲已接受。 –

相關問題