Azure,存储2.0的共享访问签名上的访问被拒绝

我无法获得共享访问签名以使用Storage 2.0 ..

我用的代码是:

if (blob.Exists()) { var expires = DateTime.UtcNow.AddMinutes(30); var sas = blob.GetSharedAccessSignature(new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy { Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = expires }); url = string.Concat(blob.Uri.AbsoluteUri, sas); } return url; 

但是如果我调试会话并将URL粘贴到浏览器中,我会收到错误:

  AuthenticationFailed  Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:c1a1dd2b-bf4a-4a6b-bab2-ab1cb9363d27 Time:2012-11-19T14:41:51.1254531Z   Signature did not match. String to sign used was r 2012-11-19T15:11:36Z /container/path/1356/pic.jpg 2012-02-12   

有人可以帮忙吗?

更新:生成的URL如下所示: https : //storageaccountname.blob.core.windows.net/container/path/1356/pic.jpg?sv = 2012-02-12&se = 2012-11-19T19%3A25%3A32Z&sr = b&SP = R&SIG = s6QIdwAGY4xC8fs4L9pK8hAGIY%2F8x58aqBcFbejYPdM%3D

我得到了同样的错误。 在我更新到2.0之前,此代码曾经工作过:

 var sharedAccessPolicy = new SharedAccessBlobPolicy { SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-10), SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30), Permissions = SharedAccessBlobPermissions.Read }; var sharedAccessSignature = _blockblob.GetSharedAccessSignature(sharedAccessPolicy); return _blockblob.Uri.AbsoluteUri + sharedAccessSignature; 

我得到了uri:

 http://127.0.0.1:10000/devstoreaccount1/original/c04d2a1c-980b-42c5-b76e-b71185f027b6.jpg?sv=2012-02-12&st=2012-11-20T08%3A30%3A24Z&se=2012-11-20T09%3A10%3A24Z&sr=b&sp=r&sig=9%2BVg6mSGqyrfr5rPlNJ6GSv%2BHN3J9k%2FWFRLYmx3xCvQ%3D 

更新,解决:

在上面的代码中,我有_blockBlob。 这是在constuctor中设置的

 var blobClient = account.CreateCloudBlobClient(); var container = blobClient.GetContainerReference(containerName); CloudBlockBlob _blockblob = container.GetBlockBlobReference(fileName); 

将最后一行(由clausndk建议)更改为

 ICloudBlob _test = container.GetBlobReferenceFromServer(fileName); 

解决了这个问题,因为在_test上调用GetSharedAccessSignature会产生不同的(有效)签名。

查看Azure存储的源代码并在我的应用程序上使用调试器,我找到了问题的原因。 在我的代码中,我有一个带有尾部斜杠(original /)的containerName。 除了GetSharedAccessSignature之外,这不是问题。 这里额外的斜线会使canonicalName混乱(在代码中添加一个斜杠,给出双斜杠),这会使签名无效。 GetBlobReferenceFromServer工作的原因是它向服务器(通过REST API)询问blob,并且生成的CloudBlockBlob删除了斜杠。

在我的代码中,我删除了斜杠,但Sandrino Di Mattia的解决方案使用.Trim(’/’)对容器名称也有效。 我认为这比使用GetBlobReferenceFromServer更受欢迎,因为它会导致额外的服务器调用。

希望CloudBlockBlobBase中的GetCanonicalName的实现将在未来更改为处理尾随斜杠(我在GitHub上为此创建了一个问题)但是现在这个“解决方法”有效。

你能试试下面的代码吗?

 var pathToMyBlob = "/path/1356/pic.jpg"; var blob = container.GetBlockBlobReference(pathToMyBlob.TrimStart('/')); var expires = DateTime.UtcNow.AddMinutes(30); var sas = blob.GetSharedAccessSignature(new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy { Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = expires }); 

看第二行,特别是调用TrimStart。 在尝试获取路径以斜杠开头的文件的blob引用时,我能够重现该问题。 通过删除斜杠,问题得到解决。 所以:

  • /path/1356/pic.jpg>不起作用
  • path / 1356 / pic.jpg>作品