我正面临有线问题..
我想允许某些用户从/向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调用检索密钥),它会抛出异常。
答案 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);