【问题标题】:404 error for Shared Access Signature with v2 of Azure Storage Client Library使用 Azure 存储客户端库 v2 的共享访问签名出现 404 错误
【发布时间】:2014-04-16 18:04:39
【问题描述】:

我正在尝试使用 Windows Azure 存储客户端库的 v2.0 为 blob 生成共享访问签名(并使用它)。 我从 this sample 开始,但它适用于 v1.7,将其转换为 2.0 会出现 404 错误。

这是我的实际代码: 服务器端,生成 SAS:

var myAccount = CloudStorageAccount.Parse(
                  ConfigurationManager.ConnectionStrings[
                              "AzureStorageConnectionString"].ConnectionString);
var myContainer = myAccount.CreateCloudBlobClient()
                                          .GetContainerReference(containerName);
myContainer.CreateIfNotExists();

string blobName = "Imports/" + DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss") 
                             + ".zip";
var myBlob = myContainer.GetBlockBlobReference(blobName);
using (var stream = 
 new MemoryStream(System.Text.Encoding.UTF8.GetBytes("Hey, I'm empty for now.")))
{
    myBlob.UploadFromStream(stream);
}

var sharedAccesSignature = myBlob.GetSharedAccessSignature(
                 new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy()
{
   Permissions = 
       Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Write 
       | Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read,
       SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
});

return myBlob.Uri.AbsoluteUri + sharedAccesSignature;

它在客户端尝试了很多东西,有时会导致 404 或 403 服务器错误。 例如我试过这个(结果:404):

var blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature));
// blobWithSharedAccessSignature here is : https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip?sv=2012-02-12&se=2012-12-01T20%3A43%3A54Z&sr=b&sp=rw&sig=h0bTUk[...]3D
// calling blobWithSharedAccessSignature from a webBrowser works.
// result here is valid for containerName : container1
var container = blobClient.GetContainerReference(containerName);
ICloudBlob blobRef = container.GetBlobReferenceFromServer(blobWithSharedAccessSignature);   ==> error 404
using (var fileStream = File.OpenRead(fileFullPath))
{
    blobRef.UploadFromStream(fileStream);
}

我尝试替换

container.GetBlobReferenceFromServer(blobWithSharedAccessSignature);

通过

container.GetBlockBlobReference(blobWithSharedAccessSignature);

我也试过替换

blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature));

通过

blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature), new StorageCredentials(blobWithSharedAccessSignature));

这会导致“403 - 禁止”错误。

有人可以通过在 v2 中提供完整示例来帮助我吗?或者告诉我是我的错误?谢谢!

更新 - 解决方案:(感谢 Sandrino Di Mattia)

// Assuming that blobWithSharedAccessSignature is : 
//  "https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip?sv=2012-02-12&se=2012-12-01T20%3A43%3A54Z&sr=b&sp=rw&sig=h0bTUkTR%2FdTF%2BVZgDUuBPHqG%2BiTtFeXK4kepBpDR2AU%3D"
Uri blobUriWithoutCredentials = new Uri(new Uri(blobWithSharedAccessSignature).GetLeftPart(UriPartial.Path));
// here blobUriWithoutCredentials is https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip
string credentials = blobWithSharedAccessSignature.Substring(blobWithSharedAccessSignature.IndexOf('?'));
// here credentials is "?sv=2012-02-12&se=2012-12-01T22%3A26%3A55Z&sr=b&sp=rw&sig=Lsk8kLyJ8TFoGNVLbFLftCIXUNlIIRPZalkhoPdUfh8%3D"
var blobClient = new CloudBlobClient(blobUriWithoutCredentials, new StorageCredentials(credentials));
ICloudBlob blobRef = blobClient.GetBlobReferenceFromServer(blobUriWithoutCredentials);
using (var fileStream = File.OpenRead(fileFullPath))
{
    blobRef.UploadFromStream(fileStream);
}

【问题讨论】:

标签: c# azure azure-storage azure-blob-storage


【解决方案1】:

初始化CloudBlobClient时需要传递2个参数

  • baseUri:不带 SAS 的 Blob url,http://test.blob.core.windows.net/temp/Imports/2012-12-01_20-56-52.zip
  • 凭据:这应该是您的 SAS,没有 URL,?sv=2012-02-12&se=2012-12-01T21%3A57%3A56Z&sr=b&sp=rw&sig=5JboXXM1Yeo%2BuI6mb18VbURluo%3D

工作样本:

var blobClient = new CloudBlobClient(new Uri(blob.Uri.AbsoluteUri), new StorageCredentials(sharedAccesSignature));
using (var fileStream = File.OpenRead(fileFullPath))
{

    blobClient.GetBlobReferenceFromServer(new Uri(blob.Uri.AbsoluteUri))
                .UploadFromStream(fileStream);
}

额外提示:您不需要获取对容器的引用。您可以通过在CloudBlobClient 上调用GetBlobReferenceFromServer 来立即访问该blob。

【讨论】:

  • 它有效,谢谢!但我根本不明白其中的逻辑:为什么 CloudBlobClient 不能仅从一个 URI 中找到自己的凭据和基本 Uri?这很奇怪!这只是 2 行代码(请参阅我对最终解决方案的编辑)。顺便说一句,非常感谢您的回答!
  • 这可能是为了将身份验证与实际的 Blob 服务实现分离。结果是,您的代码可以与 SAS 请求和“完全访问”请求(帐户名+密钥)相同,只需提供不同的 StorageCredentials
  • 我不知道你能不能帮我,你能不能看看这个问题并在那里回复我..stackoverflow.com/questions/31847102/…
  • 在我的平台 (Android) 中,我没有得到类似于 GetBlobReferenceFromServer 的方法。那我该怎么办呢?
猜你喜欢
  • 2018-07-29
  • 2023-04-05
  • 2016-09-30
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
  • 2022-10-21
  • 2018-04-23
  • 1970-01-01
相关资源
最近更新 更多