403禁止错误 - 在c#中使用Http GET请求访问Amazon S3存储桶

时间:2015-06-25 11:51:44

标签: c# rest amazon-web-services amazon-s3

我正在编写一个试图通过REST调用访问Amazon S3存储桶的c#代码。 该代码对在s3存储桶中创建的xml文件发出get请求。

我正在使用密钥和访问ID来创建将在授权标头中使用的签名。

我创建的Signature基于亚马逊的文档, http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html

我为经过身份验证的请求提供了访问s3存储桶中xml文件的权限。

我正在使用的准则,

string AccessId = "xyz";
string SecretKey = "xyz";
string bucketName = "bucket";
string filename = "filename.xml";
string httpDate = DateTime.UtcNow.ToString("ddd, dd MMM yyyy HH:mm:ss +0000\n");
string StringtoSign = "GET\n"
                      + "\n"
                      + "\n"
                      + httpDate + "\n"  
                      + "/bucketName/filename.xml";

//Creating Signature
     Encoding e_UTF = new UTF8Encoding();
     Encoding e_ASCI = new ASCIIEncoding();
     byte[] key_new= e_ASCI.GetBytes(SecretKey);
     byte[] message_new = e_UTF.GetBytes(StringtoSign);
     HMACSHA1 myhmacsha1 = new HMACSHA1(key_new);
     byte[] final=myhmacsha1.ComputeHash(message_new);
     string AWSSignature = Convert.ToBase64String(final);

// Sending request
HttpWebRequest request =    (HttpWebRequest)HttpWebRequest.Create("http://"+bucketname+".s3-us-west-2.amazonaws.com/"+filename);
request.Method = "GET";
request.Headers.Add("Authorization", "AWS"+ " " + AccessId + ":" + AWSSignature);
try
{
    // Getting response
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream stream = response.GetResponseStream();
    StreamReader sr = new StreamReader(stream);
    String ResStr = sr.ReadToEnd();
    Console.WriteLine(ResStr);
}
catch (WebException ex)
{
    var Resp = (HttpWebResponse)ex.Response;
    Stream new_str=Resp.GetResponseStream();
    StreamReader stred = new StreamReader(new_str);
    MessageBox.Show(stred.ReadToEnd().ToString());
}

如果我将xml文件的权限设置为public,则相同的代码可以正常工作。因此它必须对签名做一些事情。 我不确定我做错了什么。如果有人可以看一下它会很棒。

1 个答案:

答案 0 :(得分:0)

您需要通过发送Date或X-Amz-Date标头告诉S3您用于计算签名的日期/时间。您的代码签署请求就像发送Date标头一样,因此您应该要求HttpWebRequest发送匹配的Date标头(并确保以与HttpWebRequest相同的方式格式化它):

DateTime now = DateTime.UtcNow;
string httpDate = now.ToString("r");

...

request.Date = now;

或者,您可能需要考虑使用AWS SDK for .NET,它会为您生成正确的签名。