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 в браузер, я получаю сообщение об ошибке:
<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 ответа
Я получаю ту же ошибку. Этот код работал до того, как я обновился до 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);
решает проблему, так как вызов GetSharedAccessSignature в _test приводит к другой (действительной) подписи.
Просматривая исходный код хранилища Azure и используя отладчик в моем приложении, я нашел причину проблемы. В моем коде у меня есть containerName с косой чертой (оригинал /). Это не проблема, за исключением случаев, когда речь идет о GetSharedAccessSignature. Здесь дополнительная косая черта портит canonicalName (одна косая черта добавляется в код, дающий двойные косые черты), и это делает подпись недействительной. Причина, по которой GetBlobReferenceFromServer работает, заключается в том, что он запрашивает у серверов (через REST API) большой двоичный объект, а в результате CloudBlockBlob удаляет косую черту.
В моем коде я удалил косую черту, но решение Сандрино Ди Маттиа использовать.Trim('/') в имени контейнера также работает. Я думаю, что это предпочтительнее, чем использование GetBlobReferenceFromServer, так как это вызовет дополнительный серверный вызов.
Надеемся, что реализация GetCanonicalName в CloudBlockBlobBase будет изменена для обработки завершающих слешей в будущем (для этого я создал проблему на 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 > Не работает
- путь / 1356 / pic.jpg> Работы