如何使用 Azure 存储模拟器 blob 端点获取 blob?
How to use Azure storage emulator blob endpoint to get a blob?
下面的代码,当指向一个真实的Azure存储账户时会成功return blob内容:
var path = $"{container}/{blob}";
var rfcDate = DateTime.UtcNow.ToString("R");
var headers = "GET\n\n\n\n\n\n\n\n\n\n\n\n" +
"x-ms-blob-type:Block\n" +
$"x-ms-date:{rfcDate}\n" +
$"x-ms-version:{ServiceVersion}\n" +
$"/{AccountName}/{path}";
var uri = new Uri(BlobEndpoint + path);
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("x-ms-blob-type", "Block");
request.Headers.Add("x-ms-date", rfcDate);
request.Headers.Add("x-ms-version", ServiceVersion);
string signature = "";
using (var sha = new HMACSHA256(System.Convert.FromBase64String(AccountKey)))
{
var data = Encoding.UTF8.GetBytes(headers);
signature = System.Convert.ToBase64String(sha.ComputeHash(data));
}
var authHeader = $"SharedKey {AccountName}:{signature}";
request.Headers.Add("Authorization", authHeader);
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
但是,如果我将其配置为使用 Azure 模拟器,其中:
- 账户名 = devstoreaccount1
- 帐号密钥 = Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
- BlobEndpoint = http://127.0.0.1:10000/
- 服务版本 = 2009-09-19
我总是收到 404。我使用的是 Azure 存储模拟器 v4.6。是代码或配置不正确还是模拟器不支持?
您的代码有两个问题:
- 存储模拟器中的 Blob 服务侦听
http://127.0.0.1:1000
,但基本 URI 是 http://127.0.0.1:1000/devstoreaccount1
。
- 在计算
Signature String
(代码中的 header
变量)时,帐户名必须出现两次。这是因为帐户名称是资源 URI 路径的一部分(URL 对于 blob 将是 http://127.0.0.1:1000/devstoreaccount1/container-name/blob-name
)。
基于这些,请尝试以下代码:
static async Task<string> ReadBlobFromDevStorage()
{
var container = "temp";
var blob = "test.txt";
var ServiceVersion = "2009-09-19";
var AccountName = "devstoreaccount1";
var BlobEndpoint = "http://127.0.0.1:10000/devstoreaccount1";
var path = $"{container}/{blob}";
var AccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
var rfcDate = DateTime.UtcNow.ToString("R");
var headers = "GET\n\n\n\n\n\n\n\n\n\n\n\n" +
"x-ms-blob-type:Block\n" +
$"x-ms-date:{rfcDate}\n" +
$"x-ms-version:{ServiceVersion}\n" +
$"/{AccountName}/{AccountName}/{path}";
var uri = new Uri(BlobEndpoint + "/" + path);
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("x-ms-blob-type", "Block");
request.Headers.Add("x-ms-date", rfcDate);
request.Headers.Add("x-ms-version", ServiceVersion);
string signature = "";
using (var sha = new HMACSHA256(System.Convert.FromBase64String(AccountKey)))
{
var data = Encoding.UTF8.GetBytes(headers);
signature = System.Convert.ToBase64String(sha.ComputeHash(data));
}
var authHeader = $"SharedKey {AccountName}:{signature}";
request.Headers.Add("Authorization", authHeader);
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
return content;
}
}
下面的代码,当指向一个真实的Azure存储账户时会成功return blob内容:
var path = $"{container}/{blob}";
var rfcDate = DateTime.UtcNow.ToString("R");
var headers = "GET\n\n\n\n\n\n\n\n\n\n\n\n" +
"x-ms-blob-type:Block\n" +
$"x-ms-date:{rfcDate}\n" +
$"x-ms-version:{ServiceVersion}\n" +
$"/{AccountName}/{path}";
var uri = new Uri(BlobEndpoint + path);
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("x-ms-blob-type", "Block");
request.Headers.Add("x-ms-date", rfcDate);
request.Headers.Add("x-ms-version", ServiceVersion);
string signature = "";
using (var sha = new HMACSHA256(System.Convert.FromBase64String(AccountKey)))
{
var data = Encoding.UTF8.GetBytes(headers);
signature = System.Convert.ToBase64String(sha.ComputeHash(data));
}
var authHeader = $"SharedKey {AccountName}:{signature}";
request.Headers.Add("Authorization", authHeader);
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
但是,如果我将其配置为使用 Azure 模拟器,其中:
- 账户名 = devstoreaccount1
- 帐号密钥 = Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
- BlobEndpoint = http://127.0.0.1:10000/
- 服务版本 = 2009-09-19
我总是收到 404。我使用的是 Azure 存储模拟器 v4.6。是代码或配置不正确还是模拟器不支持?
您的代码有两个问题:
- 存储模拟器中的 Blob 服务侦听
http://127.0.0.1:1000
,但基本 URI 是http://127.0.0.1:1000/devstoreaccount1
。 - 在计算
Signature String
(代码中的header
变量)时,帐户名必须出现两次。这是因为帐户名称是资源 URI 路径的一部分(URL 对于 blob 将是http://127.0.0.1:1000/devstoreaccount1/container-name/blob-name
)。
基于这些,请尝试以下代码:
static async Task<string> ReadBlobFromDevStorage()
{
var container = "temp";
var blob = "test.txt";
var ServiceVersion = "2009-09-19";
var AccountName = "devstoreaccount1";
var BlobEndpoint = "http://127.0.0.1:10000/devstoreaccount1";
var path = $"{container}/{blob}";
var AccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
var rfcDate = DateTime.UtcNow.ToString("R");
var headers = "GET\n\n\n\n\n\n\n\n\n\n\n\n" +
"x-ms-blob-type:Block\n" +
$"x-ms-date:{rfcDate}\n" +
$"x-ms-version:{ServiceVersion}\n" +
$"/{AccountName}/{AccountName}/{path}";
var uri = new Uri(BlobEndpoint + "/" + path);
var request = new HttpRequestMessage(HttpMethod.Get, uri);
request.Headers.Add("x-ms-blob-type", "Block");
request.Headers.Add("x-ms-date", rfcDate);
request.Headers.Add("x-ms-version", ServiceVersion);
string signature = "";
using (var sha = new HMACSHA256(System.Convert.FromBase64String(AccountKey)))
{
var data = Encoding.UTF8.GetBytes(headers);
signature = System.Convert.ToBase64String(sha.ComputeHash(data));
}
var authHeader = $"SharedKey {AccountName}:{signature}";
request.Headers.Add("Authorization", authHeader);
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
return content;
}
}