在 Winrt 中使用带有 Rest API 的 Azure,签名有问题
Posted
技术标签:
【中文标题】在 Winrt 中使用带有 Rest API 的 Azure,签名有问题【英文标题】:Working with Azure in Winrt with Rest API, trouble with signature 【发布时间】:2013-03-14 05:34:50 【问题描述】:我正在尝试在 winrt 中使用 azure 存储。由于 azure 存储客户端与 winrt 不兼容,我正在尝试使用 azure 的 rest API。我正忙着把签名弄好,我可以用另一双眼睛来帮助我看看哪里出错了。
Azure 帐户提供名称和密钥属性,此方法现在构建请求,只是列出所有 blob。
'private async void BuildHTTPRequest(AzureAccount account) System.Net.Http.HttpClient request = new HttpClient();
request.BaseAddress = new Uri(string.Format("http://0.blob.core.windows.net/", account.Name));
// Always have to use UTC date/time
request.DefaultRequestHeaders.Add("x-ms-date", DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture));
string fmtStringToSign = "0\n1\n2\n3:R\n45";
request.DefaultRequestHeaders.Add("x-ms-version", "2011-08-18");
string hdr = CanonicalizeHeaders(request.DefaultRequestHeaders);
string authValue = string.Format(fmtStringToSign, "GET", "", "", "", hdr, "");
byte[] signatureByteForm = System.Text.Encoding.UTF8.GetBytes(authValue);
string hashKey = account.Key;
MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA256");
BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
var messageBuffer = CryptographicBuffer.ConvertStringToBinary(authValue, encoding);
IBuffer keyBuffer = CryptographicBuffer.ConvertStringToBinary(hashKey, encoding);
CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyBuffer);
IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer);
string hashedString = CryptographicBuffer.EncodeToBase64String(signedMessage);
String authHeader = String.Format(CultureInfo.InvariantCulture, "0 1:2", "SharedKey",
account.Name, hashedString);
request.DefaultRequestHeaders.Add("Authorization", authHeader);
// Send the request to the queue
try
var test1 = request.GetAsync("?comp=list").Result;
if (test1.IsSuccessStatusCode)
catch (WebException ex)
这应该为签名设置标题...
public string CanonicalizeHeaders(System.Net.Http.Headers.HttpRequestHeaders hdrCollection)
StringBuilder retVal = new StringBuilder();// Look for header names that start with "x-ms-" // Then sort them in case-insensitive manner.
List<string> httpStorageHeaderNameArray = new List<string>();
Dictionary<string, string> ht = new Dictionary<string, string>();
foreach (var key in hdrCollection)
if (key.Key.ToLowerInvariant().StartsWith("x-ms-", StringComparison.Ordinal))
if (ht.ContainsKey(key.Key.ToLowerInvariant()))
ht[key.Key.ToLowerInvariant()] = string.Format("0,1", ht[key.Key.ToLowerInvariant()],
hdrCollection.FirstOrDefault(m => m.Key == key.Key).ToString().Replace("\n", string.Empty).Replace("\r", string.Empty).Trim());
else
httpStorageHeaderNameArray.Add(key.Key.ToLowerInvariant());
ht.Add(key.Key.ToLowerInvariant(),
hdrCollection.FirstOrDefault(m => m.Key == key.Key).Value.FirstOrDefault().ToString().Replace("\n", string.Empty).Replace("\r", string.Empty).Trim());
httpStorageHeaderNameArray.Sort();// Now go through each header's values in the sorted order and append them to the canonicalized string.
foreach (string key in httpStorageHeaderNameArray)
retVal.AppendFormat("0:1\n", key.Trim(), ht[key]);
return retVal.ToString();
'
【问题讨论】:
【参考方案1】:最新版本的存储客户端库支持 WinRT。您可以在此处阅读更多信息:http://blogs.msdn.com/b/windowsazurestorage/archive/2012/10/29/introducing-windows-azure-storage-client-library-2-0-for-net-and-windows-runtime.aspx。我所做的是从 Github 下载源代码:https://github.com/WindowsAzure/azure-sdk-for-net,在 VS 2012 中打开解决方案并构建RT
项目以获取必要的winmd
文件。
谈到您的问题,我相信您遇到了这个问题,因为您为规范化资源字符串传递了一个空字符串:
string authValue = string.Format(fmtStringToSign, "GET", "", "", "", hdr, "")
有关创建规范化资源字符串的更多详细信息,请参阅此链接:http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx。
【讨论】:
你正式成为我的英雄。我真的不确定资源字符串中应该包含什么。真的,虽然我想要的是关于 winrt 支持的提示 :) 它会节省很多工作。谢谢!以上是关于在 Winrt 中使用带有 Rest API 的 Azure,签名有问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 REST API 中使用带有 spring mvc 的版本?
如何在 Spring Boot 中使用带有 Bearer Token 和 form-data 的 Rest Template 调用 REST Api
在mongodb中使用现有字段作为objectId来创建带有节点和表达的REST api?