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

错误:服务器未能验证请求。确保授权头的值是正确的,包括签名。

我怎样才能使它工作?

Azure REST API -服务器身份验证失败

您的加密代码出错了。: -)

<标题>代码示例

下面是"在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());
}