[英]Azure Blob Storage Shared Access Signature (SAS) - Signature did not match
[英]Azure, access denied on Shared Access Signature for Storage 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粘贴到浏览器中,则会收到错误消息:
<Error>
<Code>AuthenticationFailed</Code>
<Message>
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
</Message>
<AuthenticationErrorDetail>
Signature did not match. String to sign used was r 2012-11-19T15:11:36Z /container/path/1356/pic.jpg 2012-02-12
</AuthenticationErrorDetail>
</Error>
有人可以帮忙吗?
更新:生成的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。 这是在构造函数中设置的
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
CloudBlockBlob _blockblob = container.GetBlockBlobReference(fileName);
将最后一行(如clausndk建议)更改为
ICloudBlob _test = container.GetBlobReferenceFromServer(fileName);
解决了该问题,因为对_test的GetSharedAccessSignature调用导致了不同的(有效)签名。
查看Azure存储的源代码并在我的应用程序上使用调试器,我发现了问题的原因。 在我的代码中,我的容器名带有斜杠(原始/)。 除了涉及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引用时,我能够重现该问题。 通过删除斜杠,可以解决问题。 所以:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.