在客户端使用时,SharedAccessSignature无法正常工作

时间:2012-08-02 12:34:15

标签: c# azure

我正面临有线问题..

我想允许某些用户从/向Azure-Container读/写文件。为此,我使用SharedAccessSignature的概念。

我在RESTFUL(ASP.NET MVC4)Web服务中生成共享访问签名,客户端调用该服务来获取访问密钥。

  CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
  CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient ();
  CloudBlobContainer container = blobClient.GetContainerReference (containerName);
  container.CreateIfNotExist ();
  BlobContainerPermissions containerPermissions = new BlobContainerPermissions ();
  containerPermissions.PublicAccess = BlobContainerPublicAccessType.Off;
  container.SetPermissions (containerPermissions);
  string sas = container.GetSharedAccessSignature (new SharedAccessPolicy ()
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes (30),
            Permissions = SharedAccessPermissions.Write | SharedAccessPermissions.Read
        });
  //return sas to user

我将sas返回到他尝试使用以下代码上传blob的客户端

  CloudBlobClient sasBlobClient = new CloudBlobClient ("http://127.0.0.1:10000/devstoreaccount1", new StorageCredentialsSharedAccessSignature (sak));
  CloudBlob blob = sasBlobClient.GetBlobReference (containerName + "/myblob.txt");
  blob.UploadText ("Hello SAS World");

在最后一行客户端抛出异常

服务器无法验证请求。确保正确形成Authorization标头的值,包括签名。

内部例外: {“远程服务器返回错误:(403)禁止。”}

有趣的是,如果我在获得sas (string sas = container.GetShare....... )之后立即放置客户端代码,那么它可以正常工作。但是,如果我将我的客户端代码放在一个单独的控制台应用程序中(然后通过REST调用检索密钥),它会抛出异常。

1 个答案:

答案 0 :(得分:2)

我在控制台应用程序中测试了您的代码并且工作正常(我将sas变量传递给CloudBlobClient)。但后来我使用ASP.NET Web API设置了REST服务,并使用WebClient检索密钥:

  WebClient wc = new WebClient();
  var sas = wc.DownloadString("http://127.0.0.1:47413/api/values/1");

在Web应用程序和控制台应用程序中,我使用Trace将SAS密钥写入输出窗口,这就是结果:

  

WebApp:?se = 2012-08-02T19%3A54%3A53Z& sr = c& sp = rw& sig = oWEF7r5HpkEh%2BH1aTVKGR7VF3gbWwq84gv%2BZFbXRhOA%3D

     

客户:“?se = 2012-08-02T19%3A54%3A53Z& sr = c& sp = rw& sig = oWEF7r5HpkEh%2BH1aTVKGR7VF3gbWwq84gv%2BZFbXRhOA%3D”

正如您所看到的,SAS键看起来像是用双引号括起来的。我不知道你用什么来创建你的REST服务,但我正在使用ASP.NET Web API。在这里,它使用JSON格式化程序作为默认格式化程序。因此返回的SAS密钥是正确的,唯一的问题是它以JSON格式返回。

要获得实际的SAS密钥,您需要将其反序列化为字符串(听起来很奇怪没有?),这是Json.NET的一个示例:

var correctSAS = Newtonsoft.Json.JsonConvert.DeserializeObject<string>(sas);