Azure REST API -服务器身份验证失败
本文关键字:身份验证 失败 服务器 REST API Azure | 更新日期: 2023-09-27 18:11:17
我正在创建Windows Phone 8.1商店应用程序,能够将一些blobs上传到Azure存储。我无法使用WindowsAzure。存储库(非常奇怪),所以我尝试使用REST。我不知道出了什么事。
try
{
string time = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
string tosign = "GET'n" +
"'n" + //Content-Encoding
"'n" + //Content-Language
"0'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:" + time + "'nx-ms-version:2015-02-21'n" + //CanonicalizedHeaders
"/storage_name/'ncomp:list"; //CanonicalizedResource
string hashKey = "DHpNuYG5MXhamfbKmFPClUlNi38QiM2uqIqz07pgvpv2gmXJRwxaMlcV05pFCYsrelGYKPed9QphyJ/YnUrh5w=="; //Primary access key
MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
var messageBuffer = CryptographicBuffer.ConvertStringToBinary(tosign, BinaryStringEncoding.Utf8);
IBuffer keyBuffer = CryptographicBuffer.ConvertStringToBinary(hashKey, BinaryStringEncoding.Utf8);
CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyBuffer);
IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer);
string hashedString = CryptographicBuffer.EncodeToBase64String(signedMessage);
var client = new HttpClient();
Uri uri = new Uri("https://storage_name.blob.core.windows.net/?comp=list");
client.DefaultRequestHeaders.Add("x-ms-date", time);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-02-21");
client.DefaultRequestHeaders.Add("Authorization", "SharedKey storage_name:" + hashedString);
var response = await client.GetAsync(uri);
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}
错误:服务器未能验证请求。确保授权头的值是正确的,包括签名。
我怎样才能使它工作?
您的加密代码出错了。: -)
<标题>代码示例下面是"在utf -8编码的签名字符串上调用HMAC-SHA256算法并将结果编码为Base64"的工作代码示例。在下面的示例中,hashKey
参数是来自Azure的"主访问键",toSign
参数是来自docs的"签名字符串"。
对Windows Phone 8.1的签名进行编码
在Windows Phone 8.1中,我们使用Windows.Security.Cryptography
命名空间如下:
public string GetEncodedSignature(string toSign, string hashKey)
{
// UTF-8-encoded signature string
var utf8 = BinaryStringEncoding.Utf8;
var msgBuffer = CryptographicBuffer.ConvertStringToBinary(toSign, utf8);
// primary access key
// note the use of DecodeFromBase64String
var keyBuffer = CryptographicBuffer.DecodeFromBase64String(hashKey);
// make the HMAC-SHA256 algorithm
var alg = MacAlgorithmNames.HmacSha256;
var objMacProv = MacAlgorithmProvider.OpenAlgorithm(alg);
CryptographicHash hash = objMacProv.CreateHash(keyBuffer);
// call the HMAC-SHA256 algorithm
hash.Append(msgBuffer);
IBuffer hashMsg = hash.GetValueAndReset();
// retrieve the result!
var result = CryptographicBuffer.EncodeToBase64String(hashMsg);
return result;
}
在。net中编码签名
我还为。net创建了一个使用System.Security.Cryptography
命名空间的示例。
public static string GetEncodedSignature(string toSign, string hashKey)
{
byte[] bytes;
byte[] unicodeKey = Convert.FromBase64String(hashKey);
var utf8encodedString = Encoding.UTF8.GetBytes(toSign);
using (var hmac = new HMACSHA256(unicodeKey))
{
bytes = hmac.ComputeHash(utf8encodedString);
}
var signature = Convert.ToBase64String(bytes);
return signature;
}
当给定相同的输入时,两个代码示例产生相同的编码签名。您可以在这个生成HTTP请求的页面中更详细地看到其中一个。
<标题>参见Azure存储服务的MSDN文章认证
标题>标题>可能你已经解决了这个问题,但如果不是或其他任何人,我刚刚遇到了同样的问题,对我来说,修复它是改变内容长度为"'n"(而不是"0'n")。从2015-02-21及以后的版本开始,您不需要指定长度。
try
{
string time = DateTime.Now.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
string tosign = "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:" + time + "'nx-ms-version:2015-02-21'n" + //CanonicalizedHeaders
"/storage_name/'ncomp:list"; //CanonicalizedResource
string hashKey = "DHpNuYG5MXhamfbKmFPClUlNi38QiM2uqIqz07pgvpv2gmXJRwxaMlcV05pFCYsrelGYKPed9QphyJ/YnUrh5w=="; //Primary access key
string hashedString = GetEncodedSignature(tosign, hashKey); //Shaun's answer method
var client = new HttpClient();
Uri uri = new Uri("https://storage_name.blob.core.windows.net/?comp=list");
client.DefaultRequestHeaders.Add("x-ms-date", time);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-02-21");
client.DefaultRequestHeaders.Add("Authorization", "SharedKey storage_name:" + hashedString);
var response = await client.GetAsync(uri);
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}