C# Windows azure REST API列出容器问题
我正在尝试列出我的windows azure存储帐户中的容器。但我被一个异常所震惊C# Windows azure REST API列出容器问题,c#,asp.net,azure,azure-storage,azure-storage-blobs,C#,Asp.net,Azure,Azure Storage,Azure Storage Blobs,我正在尝试列出我的windows azure存储帐户中的容器。但我被一个异常所震惊“远程服务器返回了一个错误:(403)服务器无法验证请求。请确保授权标头的值格式正确,包括签名…” 但是我已经按照给出的说明附上了签名,有人发现我的代码有错误吗 private static String SignThis(string StringToSign,string Key,string Account) { String signature = string
“远程服务器返回了一个错误:(403)服务器无法验证请求。请确保授权标头的值格式正确,包括签名…” 但是我已经按照给出的说明附上了签名,有人发现我的代码有错误吗
private static String SignThis(string StringToSign,string Key,string Account)
{
String signature = string.Empty;
byte[] unicodeKey = Convert.FromBase64String(Key);
using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
String authorizationHeader = String.Format(
System.Globalization.CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);
return authorizationHeader;
}
static void ListContainers()
{
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
string Key = @"MyStorageAccountKey";
string Account = @"MyStorageAccountName";
DateTime dt = DateTime.UtcNow;
string dataStr = dt.ToString ("R",System.Globalization.CultureInfo.InvariantCulture);
string StringToSign = String.Format("GET\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-date:" + dataStr + "\nx-ms-version:2014-02-14\n" // headers
+ "/{0}\ncomp:list", Account);
string auth = SignThis(StringToSign, Key, Account);
string method = "GET";
string urlPath = string.Format ("https://{0}.blob.core.windows.net/?comp=list", Account);
Uri uri = new Uri(urlPath);
HttpWebRequest reque = (HttpWebRequest)WebRequest.Create(uri);
reque.Method = method;
reque.Headers.Add("Authorization", auth);
reque.Headers.Add("x-ms-date",dataStr);
reque.Headers.Add("x-ms-version", "2014-02-14");
using (HttpWebResponse response = (HttpWebResponse) reque.GetResponse ()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string text = reader.ReadToEnd();
}
}
}
编辑:我用来生成签名的字符串
GET
x-ms-date:Tue, 14 Jul 2015 18:38:16 GMT
x-ms-version:2014-02-14
/MyStorageAccountName/
comp:list
编辑:我收到了异常响应:
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:2fc74ef8-0001-0083-2664-be8850000000
Time:2015-07-14T18:38:18.0831721Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request '5rqWNl2i8kuZF6haCRqFr1S0viOM9eLjz4L/zU6GCsg=' is not the same as any computed signature. Server used following string to sign: 'GET
x-ms-date:Tue, 14 Jul 2015 18:38:16 GMT
x-ms-version:2014-02-14
/MyStorageAccountName/
comp:list'.</AuthenticationErrorDetail></Error>
最终编辑:在完成gauvrav指定的所有更改后,我发现我使用的storagekey是错误的,在更换正确的storagekey后,它工作正常
此错误可能还有其他更改:请参阅此请将您的
StringToSign
更改为:
string StringToSign = String.Format("GET\n"
+ "\n" // content encoding
+ "\n" // content language
+ "\n" // content length
+ "\n" // content md5
+ "\n" // content type
+ "\n" // date
+ "\n" // if modified since
+ "\n" // if match
+ "\n" // if none match
+ "\n" // if unmodified since
+ "\n" // range
+ "x-ms-date:" + dataStr + "\nx-ms-version:2014-02-14\n" // headers
+ "/{0}/\ncomp:list", Account);//Notice an extra "/" after "{0}"
帐户名占位符(上面代码的最后一行)后缺少一个
/
。完成此操作后,您应该能够看到以XML格式返回的容器列表。错误响应应包括要对所使用的存储服务进行签名的字符串,以便您可以使用该字符串验证是否缺少要签名的字符串。谢谢,您能解释如何获取“要签名的字符串”的值吗@SerdarOzler Microsoft的意思是,如果您运行代码并让Fiddler运行(或通过解析收到的WebException响应来检查错误),您将在错误消息中看到服务器使用的StringToSign。您可以将其与StringToSign进行比较,以查看不匹配的内容。我用这个技巧在你的代码中找到了问题。谢谢你指出gaurav。我改变了它,得到了同样的错误。我想还有别的错误吗?嗯…那太奇怪了。我刚试过,对我来说效果非常好。这是我的代码副本:。你能运行你的代码,在Fiddler中跟踪请求/响应并在这里共享吗?403个错误的另外两个可能原因是-1)不正确的帐户密钥2)计算机上的时钟慢(比如超过15-20分钟)。请检查一下这些。你的回答给了我们很大的希望。我以前没有试过小提琴手,我会试一下,很快回复你。谢谢你的回复。如果没有Fiddler,请尝试以下代码:。我已经包含了获取WebException中返回的错误字符串的代码。关于你的问题,不是特别的。dataStr
以GMT为单位显示时间,如果您不在同一时区,该时间将不同于您计算机的日期时间。谢谢。您是否也可以将根据您的代码计算的StringToSign
也放在您的问题中?请用最新的错误消息更新您的问题,以便我们可以一起比较这两个问题。