c# - Azure Blob 403 禁止使用 SAS 创建和使用 BlobContainer

标签 c# azure azure-blob-storage

我正在使用从这篇 MSDN 文章中复制和修改的代码:

MSDN article about Azure SAS usage

我正在使用 Azure 存储模拟器并且可以生成 SAS。这是一个例子:

http://127.0.0.1:10000/devstoreaccount1/7373df60-ad5f-462e-a55d-15c21c2de0e1?sv=2015-04-05&sr=c&si=ac&sig=bQAsuNUsj6MycN0aTyurVugHBMOlokwsXJA9xv7VeiU%3D

我可以使用 Edge 浏览器通过附加以下内容列出 blob 容器:

&comp=list&restype=container

这样我的链接现在看起来像这样:

http://127.0.0.1:10000/devstoreaccount1/7373df60-ad5f-462e-a55d-15c21c2de0e1?sv=2015-04-05&sr=c&si=ac&sig=bQAsuNUsj6MycN0aTyurVugHBMOlokwsXJA9xv7VeiU%3D&comp=list&restype=container

这让我认为 SAS 是正确的并且存储模拟器正在工作。浏览器显示容器及其中所有 blob 的信息。

我可以检查存储模拟器日志并看到此消息:

4/21/2016 3:56:10 PM [AuthorizationFailure] [ActivityId=a79d230e-6596-4e43-8ef9-58943ee91b58] Unauthorized: Signed access not supported for this request with FailureReason InvalidOperationSAS

这是我用来创建 SAS 的代码:

    String policyName = "ac";

var storedPolicy = new SharedAccessBlobPolicy()
{
   SharedAccessExpiryTime = DateTime.UtcNow.AddHours(expireHours),
   Permissions = SharedAccessBlobPermissions.Read |
   SharedAccessBlobPermissions.List |
   SharedAccessBlobPermissions.Delete
};

var permissions = container.GetPermissions();

permissions.SharedAccessPolicies.Clear();

permissions.SharedAccessPolicies.Add(policyName, storedPolicy);

container.SetPermissions(permissions);

string sasContainerToken = container.GetSharedAccessSignature(null, policyName);

// Return the URI string for the container, including the SAS token.

return container.Uri + sasContainerToken;

下面是我使用 SAS 创建 CloudBlobContainer 的代码:

CloudBlobContainer container = new CloudBlobContainer( new Uri(sas) );   // AzureBlob.GetBlobContainer(sas); // gets a new container

if ( ! container.Exists() ) // throws exception
{
   throw new Exception("Container no longer exists for sas " + sas);
}

container.FetchAttributes();

这是一个异常(exception):

   Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (403) Forbidden. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden.
   at System.Net.HttpWebRequest.GetResponse()
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Core\\Executor\\Executor.cs:line 677
   --- End of inner exception stack trace ---
   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Core\\Executor\\Executor.cs:line 604
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(Boolean primaryOnly, BlobRequestOptions requestOptions, OperationContext operationContext) in c:
    \\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Blob\\CloudBlobContainer.cs:line 1406
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.Exists(BlobRequestOptions requestOptions, OperationContext operationContext) in c:\\Program Files (x86)\\Jenkins\\workspace\\release_dotnet_master\\Lib\\ClassLibraryCommon\\Blob\\CloudBlobContainer.cs:line 1393

这是一篇似乎是远亲的文章的链接。

SO question about SAS

最佳答案

您的代码失败的原因是您创建的是服务共享访问签名(服务 SAS),而不是帐户共享访问签名(帐户 SAS)。为了创建 Blob 容器,您需要使用 Account SAS 而不是 Service SAS。

从此页面:https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx

An account-level SAS, introduced with version 2015-04-05. The account SAS delegates access to resources in one or more of the storage services. All of the operations available via a service SAS are also available via an account SAS. Additionally, with the account SAS, you can delegate access to operations that apply to a given service, such as Get/Set Service Properties and Get Service Stats. You can also delegate access to read, write, and delete operations on blob containers, tables, queues, and file shares that are not permitted with a service SAS. See Constructing an Account SAS for more information about account SAS.

以下是创建 Account SAS 并使用它来创建 Blob 容器的示例代码:

        var storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
        var blobClient = storageAccount.CreateCloudBlobClient();
        var blobSharedAccessPolicy = new SharedAccessAccountPolicy()
        {
            Services = SharedAccessAccountServices.Blob,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1),
            Permissions = SharedAccessAccountPermissions.Write,
            ResourceTypes = SharedAccessAccountResourceTypes.Container
        };
        var sas = storageAccount.GetSharedAccessSignature(blobSharedAccessPolicy);
        var containerName = "created-using-account-sas";
        var containerUri = string.Format("{0}{1}", storageAccount.BlobEndpoint, containerName);
        var blobContainer = new CloudBlobContainer(new Uri(containerUri), new StorageCredentials(sas));
        blobContainer.Create();
        Console.WriteLine("Container created....");

关于c# - Azure Blob 403 禁止使用 SAS 创建和使用 BlobContainer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36781458/

相关文章:

c# - MVC : Problems to pass currency in decimal parameter

azure - 如何使用Rest API作为Azure数据工厂中数据流的源?

azure - 管理存储访问策略

python - 在 Blob 存储中创建文件夹层次结构时生成意外链接

c# - 在 foreach 循环中删除一个节点

c# - 新的关键字和方法隐藏

c# - 如何使用 C# 获取给定路径(可以是目录或文件,甚至是完整路径)的完整路径?

azure - 如何获取 terraform 计划以在集群内创建私有(private) AKS 集群和命名空间?

azure - 我可以将多个 Azure 订阅链接到单个团队服务帐户 (VSTS) 吗?

使用 ARM 的 Azure Blob 存储容器存储访问策略