2013-10-30 115 views
5

我试图让一些代码工作从S3使用REST API通过C#获取文件。我看到其他人做类似的事情,但由于某种原因,我不断收到403错误。我试图用.Net的AWS SDK做同样的事情,因此我认为这是我创建授权标题的方式。亚马逊S3 REST API 403错误c#

任何人都可以摆脱这个问题吗?

string awsAccessId = "***"; 
string awsSecretKey = "***"; 
string bucketName = "thebucket"; 

string httpDate = DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss +0000\n"); 
       string canonicalString = "GET\n" 
             + "\n" 
             + "\n" 
             + "x-amz-date:" + httpDate + "\n" 
             + "/" + bucketName + "/readme.txt"; 

       // now encode the canonical string 
       Encoding ae = new UTF8Encoding(); 
       // create a hashing object 
       HMACSHA1 signature = new HMACSHA1(); 
       // secretId is the hash key 
       signature.Key = ae.GetBytes(awsSecretKey); 
       byte[] bytes = ae.GetBytes(canonicalString); 
       byte[] moreBytes = signature.ComputeHash(bytes); 
       // convert the hash byte array into a base64 encoding 
       string encodedCanonical = Convert.ToBase64String(moreBytes); 

       // Send the request 
       HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://" + bucketName +".s3.amazonaws.com/readme.txt"); 
       request.Headers.Add("x-amz-date", httpDate); 
       request.Headers.Add("Authorization", "AWS " + awsAccessId + ":" + encodedCanonical); 
       request.Method = "GET"; 

       // Get the response 
       HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
       Console.WriteLine(response.StatusCode); 
       Console.Read(); 
+0

为什么不使用sdk如果它工作? –

+0

我希望将它放入SSIS脚本任务 – MarkJ

回答

1

我不知道这是否是唯一的问题,但它看起来像一个明确的问题:

+ "x-amz-date:" + httpDate + "\n" 

x-amz-date是取代了日期的标题:标题在HTTP请求本身,而是在字符串中签,你只要把日期,无“X-AMZ-日期:”或任何在它前面,根据例子:

GET\n 
\n 
\n 
Tue, 27 Mar 2007 19:36:42 +0000\n 
/johnsmith/photos/puppy.jpg 

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationRequestCanonicalization

只有一个正确的签名可以为请求生成。 S3将生成该签名,并将其与您发送的签名进行比较,因此在字符串到符号中没有单个字节的空间出现错误。

+0

感谢您的建议。我做了修改,但不幸的是它仍然不起作用。 – MarkJ

+0

403消息是否返回了一个错误,该错误给了您要签名的字符串并告诉您签名不匹配,或者没有?错误说的是什么? (在响应正文中) –

+0

错误消息指出签名不匹配:SignatureDoesNotMatch我们计算的请求签名与您提供的签名不匹配。检查你的密钥和签名方法。 MarkJ

1

我测试了你的代码,它的工作原理!你只需要额外的\ n加上改变http到https,你就完成了。

string stringToConvert = "GET\n" 
          + "\n" 
          + "\n" 
          + "\n" 
          + "x-amz-date:" + timeStamp + "\n" 
          + "/" + bucketName + "/" + FileName; 

亚马逊Rest API没有很好的文档,缺乏示例会让所有人转而使用SDK。