gpt4 book ai didi

azure - 对 Azure 表的 POST 请求中的授权 header

转载 作者:行者123 更新时间:2023-12-03 03:18:25 24 4
gpt4 key购买 nike

为了将实体插入 Azure 表,我已经完成并尝试了所有方法,但到目前为止,我仍然收到相同的错误“StatusCode:403,ReasonPhrase:'服务器无法验证请求。请确保该值授权 header 的格式正确,包括签名。'"

现在,我尝试使用 ShareKey 和 SharedKeyLite(Azure 存储资源管理器使用 SharedKeyLite)

public static async Task<string> InsertEntityAsync(string tableName, Position position)
{
string uri = @"https://" + Utilities.Account + ".table.core.windows.net/" + tableName;
return await Utilities.UploadEntityAsync(tableName,uri,position);
}
public static async Task<string> UploadEntityAsync(string urlPath, string uri, Position position)
{
string body = buildBodyForInsertOperation(position);

HttpClient request = new HttpClient();
string formatedTime = Authentication.FormatedTime();
request.DefaultRequestHeaders.Add("x-ms-date", formatedTime);

//Adding the Authorization header to the request
string authorization = Authentication.GetSignedString("POST",formatedTime, urlPath, Utilities.Account, Utilities.Key);
request.DefaultRequestHeaders.Add("Authorization", authorization);

request.DefaultRequestHeaders.TryAddWithoutValidation("Content-Length", body.Length.ToString());


HttpResponseMessage messageResult = await request.PostAsync(uri, new StringContent(body, UTF8Encoding.UTF8, "application/atom+xml"));
return messageResult.ToString();
}

public static string GetSignedString(string httpMethod, string time, string urlPath, string account, string key)
{
String contentMD5 = String.Empty;
String contentType = "application/atom+xml";
String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
String stringToSign = String.Format(
"{0}\n{1}\n{2}\n{3}\n{4}",
httpMethod,
contentMD5,
contentType,
time,
canonicalizedResource);

string signedKey = SignThis(stringToSign, key, account);
return signedKey;
}
private static String SignThis(String canonicalizedString,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(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}

String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKeyLite",
Account,
signature);

return authorizationHeader;
}

时间参数的格式是根据Azure要求的,除此之外我不知道还能做什么或尝试什么。我尝试在没有 httpMethod、没有 contentMD5、没有内容类型和各种组合的情况下发出请求,但仍然如此。

我非常确定 SignThis(...) 方法有效,因为我还使用它来签署查询实体的 GET 请求,因此任何帮助或文字都会对我有很大帮助。谢谢

/已编辑/我附加了 UploadEntityAsync 方法,在我的例子中,我在 Azure 中有一个名为 Position 的表,所以我正在构建 XML,无论如何,这不是错误的原因,因为我已将我构建的 XML 与 Azure 存储资源管理器的 XML 进行了比较Fiddler,没问题。唯一的问题是签名

最佳答案

所以我发现代码有一些问题:

  • 您已选择使用 SharedKeyLite,但您在代码中用于创建 stringToSign 的格式适用于 <强>SharedKey。如果您想使用 SharedKeyLite,请尝试使用如下内容创建 stringToSign:

        stringToSign = String.Format("{0}\n{1}", time, canonicalizedResource);

欲了解更多详情,请参阅此处:http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx

  • 我发现您创建 StringContent 的方式存在问题。由于某种原因,如果我使用你的代码,我总是会收到 403 错误。试试这个:

        var stringContent = new StringContent(body);
    stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/atom+xml");
    HttpResponseMessage messageResult = await request.PostAsync(uri, stringContent);

请尝试使用此代码。它使用 SharedKey:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace SOPostToAzureTable
{
static class Utilities
{
internal static string Account = "account name";

internal static string Key = "account key";
}

class Program
{
static void Main(string[] args)
{
var task = Task.Factory.StartNew(() => InsertEntityAsync("SOTest"));
Task[] tasks = new Task[1];
tasks[0] = task;
Task.WaitAll(tasks);
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}

public static async Task<string> InsertEntityAsync(string tableName)
{
string uri = @"https://" + Utilities.Account + ".table.core.windows.net/" + tableName;
return await UploadEntityAsync(tableName, uri);
}
public static async Task<string> UploadEntityAsync(string urlPath, string uri)
{
string body = @"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>
<entry
xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices""
xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata""
xmlns=""http://www.w3.org/2005/Atom"">
<title />
<updated>2013-08-30T21:03:45.4991966Z</updated>
<author>
<name />
</author>
<id />
<content type=""application/xml"">
<m:properties>
<d:PartitionKey>SOTest</d:PartitionKey>
<d:RowKey>{0}</d:RowKey>
<d:A m:type=""Edm.String"">A</d:A><d:B m:type=""Edm.String"">B</d:B>
</m:properties>
</content>
</entry>";
body = string.Format(body, Guid.NewGuid());

HttpClient request = new HttpClient();
string formatedTime = DateTime.UtcNow.ToString("R");
request.DefaultRequestHeaders.Add("x-ms-date", formatedTime);

//Adding the Authorization header to the request
string authorization = GetSignedString("POST", formatedTime, urlPath, Utilities.Account, Utilities.Key);
request.DefaultRequestHeaders.Add("Authorization", authorization);

request.DefaultRequestHeaders.TryAddWithoutValidation("Content-Length", body.Length.ToString());
var stringContent = new StringContent(body);
stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/atom+xml");
HttpResponseMessage messageResult = await request.PostAsync(uri, stringContent);
return messageResult.ToString();
}

public static string GetSignedString(string httpMethod, string time, string urlPath, string account, string key)
{
String contentMD5 = String.Empty;
String contentType = "application/atom+xml";
String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
//stringToSign format for SharedKey
String stringToSign = String.Format(
"{0}\n{1}\n{2}\n{3}\n{4}",
httpMethod,
contentMD5,
contentType,
time,
canonicalizedResource);
//stringToSign format for SharedKeyLite
//stringToSign = String.Format("{0}\n{1}", time, canonicalizedResource);
string signedKey = SignThis(stringToSign, key, account);
return signedKey;
}

private static String SignThis(String canonicalizedString, 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(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}

String authorizationHeader = String.Format(
CultureInfo.InvariantCulture,
"{0} {1}:{2}",
"SharedKey",
Account,
signature);

return authorizationHeader;
}

}
}

关于azure - 对 Azure 表的 POST 请求中的授权 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18536581/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com