Windows Azure共享访问签名始终提供:禁止403

时间:2013-07-09 21:15:20

标签: azure azure-storage azure-storage-blobs

我正在尝试获取单个blob的共享访问签名,然后使用REST api下载blob。但是,我总是得到一个禁止的403错误消息。存储模拟器和云都有。这是我的代码:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse("myConnectionStringHere...");

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("containerName");
CloudBlob blob = container.GetBlobReference("blobName");

string sasToken = blob.GetSharedAccessSignature(new SharedAccessPolicy()
            {
                Permissions = SharedAccessPermission.Read,
                SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromHours(24)
            }
            );

string completeUri = string.Format(CultureInfo.InvariantCulture, "{0}{1}", blob.Uri, sasToken);

// now use the uri to make the rest call and download
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(completeUri);
request.Method = "GET";
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream s = resp.GetResponseStream())
        {
            using (FileStream fs = new FileStream("test.jpg", FileMode.Create, FileAccess.Write))
                {
                        byte[] buffer = new byte[8 * 1024];
                        int len;
                        while ((len = s.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            fs.Write(buffer, 0, len);
                        }
                    }
                }
            }

我在调用GetResponse时一直收到403错误。任何帮助表示赞赏!

编辑:忘了提及:我正在使用最新的azure sdk(2.0)

编辑2:我进行了很多实验,找到了一个名为Azure Management Studio的工具。该工具可以创建SAS令牌。我这样做了,并将它与我的REST调用代码一起使用。这工作得很好,所以错误必须在我编写的令牌创建代码中。但是,sas字符串的格式完全相同。我不知道还有什么可以尝试

1 个答案:

答案 0 :(得分:7)

我注意到的一些事情:

  1. 您提到您正在使用SDK 2.0,但我认为您并未使用最新的存储客户端库(2.0.6)。从您的代码中,您似乎仍在使用旧的存储客户端库(1.8)。如果您引用Microsoft.WindowsAzure.StorageClientMicrosoft.WindowsAzure.Storage,请查看您的代码。如果它是前者,那么您使用的是旧库。
  2. 如果您正在使用旧的存储客户端库,那么请注意,对于使用旧的存储REST API的旧存储客户端库,对于匿名SAS令牌(即没有容器访问策略的令牌),您可以使用旧的存储客户端库。 t指定从当前时间起超过1小时的到期时间(当然是UTC)。如果我尝试使用您的URL,则会收到以下错误消息(在AuthenticationErrorDetail node:
  3. 下)
      

    没有签名标识符的访问时间窗口不能超过1   小时

    您可以尝试创建一个有效期不到1小时的SAS令牌吗? E.g。

    var sasToken = blob.GetSharedAccessSignature(new SharedAccessPolicy
        {
            Permissions = SharedAccessPermission.Read,
            SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(30)
        }
    );
    

    如果您仍想使用旧版存储客户端库,则可以选择以下几种方法:

    1. 如上所述,创建一个有效期不到一小时的SAS令牌。
    2. 使用容器级访问策略创建SAS令牌。使用容器级访问策略,您将能够定义有效期超过1小时的SAS令牌。有关详情,请点击此处:http://msdn.microsoft.com/en-us/library/windowsazure/ee393341.aspx
    3. 如果使用新的存储客户端库,则可以在不使用容器访问策略的情况下定义更长持续时间的令牌。但是,两个版本的库之间存在很多差异,从旧版本迁移到较新版本并非易事。几天前我写了一篇关于将代码从旧版本迁移到更新版本的博客文章。你可以在这里阅读:http://gauravmantri.com/tag/storage-client-library/。最后,我写了一篇关于SAS的博客文章,你可以在这里阅读:http://gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/