Виртуальные каталоги хранилища BLOB-объектов Azure с использованием сигнатур общего доступа

Я не могу заставить политики общего доступа работать с виртуальными каталогами в хранилище больших двоичных объектов. Он отлично работает для контейнеров. Насколько я знаю, виртуальные каталоги являются контейнерами, поэтому SAS должен работать?

Когда я пытаюсь получить доступ к ресурсу в виртуальном каталоге с помощью SAS, я получаю такой ответ:

<?xml version="1.0" encoding="utf-8"?>
<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:XXXXXXXX-000X-00XX-XXXX-XXXXXX000000 Time:2016-08-15T13:28:57.6925768Z</Message>
    <AuthenticationErrorDetail>Signature did not match. String to sign used was r 2016-08-15T13:29:53Z /blob/xxxxxxxxxx/mycontainer 2015-12-11</AuthenticationErrorDetail>
</Error>

Пример кода для демонстрации:

public static async Task<string> GetFilePath()
{
    var storageAccount = CloudStorageAccount.Parse( "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxxx;AccountKey=xxxxxxxxxx" );
    var blobClient = storageAccount.CreateCloudBlobClient();

    var containerName = "mycontainer/myvd";     // remove /myvd and SAS will work fine
    var containerReference = blobClient.GetContainerReference( containerName );

    var blobName = "readme.txt";
    var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );

    var sasConstraints = new SharedAccessBlobPolicy();

    sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes( 1 );
    sasConstraints.Permissions = SharedAccessBlobPermissions.Read;

    var sasContainerToken = containerReference.GetSharedAccessSignature( sasConstraints );

    var path = $"{blobClient.BaseUri.ToString()}{containerName}/{blobName}{sasContainerToken}";

    return path;
}

1 ответ

Решение

Причина этой ошибки в том, что Shared Access Signatures поддерживаются только на уровне контейнера больших двоичных объектов или на уровне больших двоичных объектов. На самом деле в хранилище BLOB-объектов Azure нет такого понятия, как Virtual Directory; он поддерживает только двухуровневую иерархию: Blob Container & Blob. Virtual Directory это просто префикс, который вы применяете к имени файла (блоба).

Исходя из этого, я бы рекомендовал внести следующие изменения в ваш код:

var containerName = "mycontainer";     // remove /myvd and SAS will work fine
var containerReference = blobClient.GetContainerReference( containerName );

var blobName = "myvd/readme.txt"; //Your blob name is actually "myvd/readme.txt"
var blobReference = await containerReference.GetBlobReferenceFromServerAsync( blobName );
Другие вопросы по тегам