c# - 使用 REST API 在 Azure 中创建表
问题描述
有没有人尝试使用 REST API 在存储帐户中创建表?如果我使用 SharedKeyLite 授权,我可以毫无问题地做到这一点。但是,当使用 SharedKey 授权时,身份验证不断失败。
我的猜测是它必须与授权签名中的“Content-MD5”值有关。该文档对 Content-MD5 值有点模糊,我在文档中找不到生成 Content-MD5 的推荐方法。
我找不到使用 C# 的示例。我发现的唯一示例是使用 Powershell,它使用 Content-MD5 的空字符串。但是,这不适用于我的情况。
这是我的代码:
public static void CreateTable(string storageAccount, string storageKey, string tableName)
{
var client = new HttpClient();
string date = DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture);
client.DefaultRequestHeaders.Add("x-ms-date", date);
string msVersion = "2018-03-28";
client.DefaultRequestHeaders.Add("x-ms-version", msVersion);
client.DefaultRequestHeaders.Add("MaxDataServiceVersion", "3.0;NetFx");
client.DefaultRequestHeaders.Add("DataServiceVersion", "3.0;NetFx");
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=nometadata");
string payload = "{ \"TableName\":\""+ tableName +"\" }";
int contentLength = GetContentLength(payload);
string authH = "SharedKey " + storageAccount + ":" + CreateTableSignature("POST", payload, "application/json", date, storageAccount + "/Tables", storageKey, new List<string>() { });
client.DefaultRequestHeaders.Add("Authorization", authH);
string requestUri = $"https://{storageAccount}.table.core.windows.net/Tables";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri);
request.Content = new StringContent(payload,
Encoding.UTF8,
"application/json");
request.Content.Headers.ContentLength = contentLength;
client.SendAsync(request)
.ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
});
}
public static string CreateTableSignature(string verb, string content, string contentType, string date, string resource, string key, List<string> canonicalizedResourceParms)
{
string msgSignature = verb + "\n" +
CreateMD5(content) + "\n" +
contentType + "\n" +
date + "\n";
msgSignature += "/" + resource;
foreach (string parm in canonicalizedResourceParms)
msgSignature += "\n" + parm;
byte[] SignatureBytes = Encoding.UTF8.GetBytes(msgSignature);
// Create the HMACSHA256 version of the storage key.
HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(key));
// Compute the hash of the SignatureBytes and convert it to a base64 string.
return Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
}
public static string CreateMD5(string input)
{
// Use input string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
return Convert.ToBase64String(hashBytes);
}
}
解决方案
两点修复。
内容类型
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
在这个方法中,SDK实际上是
application/json; charset=utf-8
在我们发送请求的时候设置的。这也意味着签名需要application/json; charset=utf-8
。或者我建议您删除该误导性内容类型设置并使用
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
内容-MD5
不需要签名,可以留空。否则,如果要放入签名中,则需要先添加相应的请求头。
request.Content.Headers.ContentMD5 = Convert.FromBase64String(CreateMD5(payload));
此外,在 CreateMD5() 方法中,Encoding 应该是 UTF8
System.Text.Encoding.UTF8.GetBytes(input);
推荐阅读
- vue.js - 通过插槽 Vue 3 访问 Vue 组件
- javascript - 如何在 NextJS 应用程序中使用 SWR 呈现来自 GraphQL 的 Apollo Server 实例的数据?
- ios - React Native Detox - 本地和 CI 有不同的结果
- c# - 打字稿 下载 PDF 文件
- .net - 使用 GitHub Actions 在 .net 应用程序中填充特定于环境的变量
- python - Errno 22 文件路径的参数无效
- sql - Redshift - 断言代码:SELECT column1 FROM my.view 上的 1000,但不在 SELECT * FROM my.view 上
- c - 如果它们的数量由输入而不是由变量确定,我如何加载然后打印多个数字
- python - 从字符串变量创建列表
- python - 如何根据analyze_recording()的“分析”中包含的信息在psynet中试用后显示自定义反馈?