Вопрос по – Как использовать SharedAccessSignature для доступа к BLOB-объектам

6

Я пытаюсь получить доступ к BLOB-объекту, хранящемуся в закрытом контейнере в Windows Azure. Контейнер имеет подпись общего доступа, но когда я пытаюсь чтобы получить доступ к BLOB-объекту, я получил StorgeClientException & quot; Серверу не удалось аутентифицировать запрос. Убедитесь, что заголовок авторизации сформирован правильно включая подпись & quot ;.

Код, который создал контейнер и загрузил BLOB-объект, выглядит следующим образом:

<code>// create the container, set a Shared Access Signature, and share it 

// first this to do is to create the connnection to the storage account
// this should be in app.config but as this isa test it will just be implemented
// here: 
// add a reference to Microsoft.WindowsAzure.StorageClient 
// and Microsoft.WindowsAzure.StorageClient set up the objects
//storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["ConnectionString"]);
blobClient = storageAccount.CreateCloudBlobClient();

// get a reference tot he container for the shared access signature
container = blobClient.GetContainerReference("blobcontainer");
container.CreateIfNotExist();

// now create the permissions policy to use and a public access setting
var permissions = container.GetPermissions();
permissions.SharedAccessPolicies.Remove("accesspolicy");
permissions.SharedAccessPolicies.Add("accesspolicy", new SharedAccessPolicy
                                                               {
                                                                   // this policy is live immediately
                                                                   // if the policy should be delatyed then use:
                                                                   //SharedAccessStartTime = DateTime.Now.Add(T); where T is some timespan
                                                                   SharedAccessExpiryTime =
                                                                       DateTime.UtcNow.AddYears(2),
                                                                   Permissions =
                                                                       SharedAccessPermissions.Read | SharedAccessPermissions.Write
                                                               });

// turn off public access
permissions.PublicAccess = BlobContainerPublicAccessType.Off;

// set the permission on the ocntianer
container.SetPermissions(permissions);

 var sas = container.GetSharedAccessSignature(new SharedAccessPolicy(), "accesspolicy");


StorageCredentialsSharedAccessSignature credentials = new StorageCredentialsSharedAccessSignature(sas);
CloudBlobClient client = new CloudBlobClient(storageAccount.BlobEndpoint,
                                             new StorageCredentialsSharedAccessSignature(sas));

CloudBlob sasblob = client.GetBlobReference("blobcontainer/someblob.txt");
sasblob.UploadText("I want to read this text via a rest call");

// write the SAS to file so I can use it later in other apps
using (var writer = new StreamWriter(@"C:\policy.txt"))
{
    writer.WriteLine(container.GetSharedAccessSignature(new SharedAccessPolicy(), "securedblobpolicy"));
}
</code>

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

<code>// the storace credentials shared access signature is copied directly from the text file "c:\policy.txt"
CloudBlobClient client = new CloudBlobClient("https://my.azurestorage.windows.net/", new StorageCredentialsSharedAccessSignature("?sr=c&si=accesspolicy&sig=0PMoXpht2TF1Jr0uYPfUQnLaPMiXrqegmjYzeg69%2FCI%3D"));

CloudBlob blob = client.GetBlobReference("blobcontainer/someblob.txt");

Console.WriteLine(blob.DownloadText());
Console.ReadLine();
</code>

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

Любая помощь очень ценится.

Ваш Ответ

2   ответа
3

Почему это

writer.WriteLine(container.GetSharedAccessSignature(new SharedAccessPolicy(), "securedblobpolicy"));

и не пишуsas Строка, которую вы уже создали?

Уже поздно, и я могу что-то упустить, но, возможно, вы не сохраняете ту же подпись доступа, которую используете для записи файла.

Также, возможно, это не имеет отношения к делу, но я считаю, что количество политик для всего контейнера может быть ограничено. Вы загружаете несколько файлов в один контейнер с этим кодом и каждый раз создаете новый контейнер sas?

В общем, я думаю, что было бы лучше запросить sas для отдельного блоба в тот момент, когда он вам нужен, с коротким сроком годности.

container.GetSharedAccessSignature (new SharedAccessPolicy (), "securedblobpolicy")) возвращает строку sas из контейнера (или, по крайней мере, я предполагаю, что это происходит, я могу ошибаться.,) crunchy
Боже, это было больно. Так что, очевидно, я не получал тот же ключ, когда использовал метод GetSharedAccessSignature. Спасибо, что указал на это, Марк. Теперь мне просто нужно разобраться с чувством себя дураком crunchy
Рад быть полезным - и не чувствовать себя плохо - мы все делаем это! Mark Willsher
1

"My..windows.net" - просто опечатка? Я ожидал бы что-то там вроде "https: //Сче .Blob.core.windows.net».

В противном случае код выглядит очень похоже на код вhttp: //blog.smarx.com/posts/shared-access-signatures-are-easy-these-day, который работает.

my.azurestorage.windows.net существует, так как нет необходимости публиковать информацию об учетной записи. И код может выглядеть очень похоже на код в блоге, на который вы ссылались, и он работает в определенной степени, но он не разрешает анонимный доступ к BLOB-объекту с использованием подписи общего доступа. Это проблема crunchy
Но чтобы быть уверенным, что твоя фактическая стоимость заканчивается на.blob.core.windows.net, правильно? (И префикс это имя вашей учетной записи хранения?) smarx
значение в реальном приложении - это адрес контейнера. У меня пока нет открытого кода, но то, что там, является точным, поскольку я могу получить доступ к контейнерам и BLOB-объектам, когда я предоставляю учетные данные учетной записи. Я все еще не уверен, почему названная политика не возвращала правильные значения, но она работает сейчас. Спасибо за вклад. crunchy

Похожие вопросы