7

我试图让一些代码通过 C# 使用 REST API 从 S3 获取文件。我见过其他人做类似的事情,但由于某种原因,我不断收到 403 错误。我尝试使用适用于 .Net 的 AWS 开发工具包做同样的事情,它可以工作,所以我认为这是我创建授权标头的方式。

请问有人能对此有所了解吗?

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();
4

2 回答 2

3

我测试了你的代码,它有效!你只需要一个额外的 \n 加上将 http 更改为 https 就可以了。

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

Amazon Rest API 没有很好的文档,缺乏示例让大家转而使用 SDK。

于 2014-10-02T18:48:58.360 回答
2

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

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

x-amz-date是 HTTP 请求本身中取代 Date: 标头的标头,但在要签名的字符串中,您只需输入日期,没有“x-amz-date:”或任何前面的内容,根据示例:

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 将生成该签名,并将其与您发送的签名进行比较,因此签名字符串中没有一个字节的错误空间。

于 2013-10-31T01:03:46.083 回答