2012-05-04 2 views
5

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

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

// 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")); 
} 

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

// 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(); 

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

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

ответ

1

Есть ли «my.azurestorage.windows.net» только опечатка? Я бы ожидал чего-то вроде «https: // аккаунт .blob.core.windows.net».

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

+0

my.azurestorage.windows.net есть, так как нет необходимости публиковать информацию об учетной записи. И код может выглядеть довольно похоже на код в блоге, на который вы ссылались, и он работает в определенной степени, но он не позволяет анонимному доступу к блобу с использованием общей подписки доступа. Это проблема! – crunchy

+0

Но, конечно, ваше фактическое значение заканчивается на '.blob.core.windows.net', правильно? (И префикс - это имя вашей учетной записи хранилища?) – smarx

+0

Значение в фактическом приложении - это адрес для контейнера. У меня сейчас нет моего кода, но то, что там, точно, я могу получить доступ к контейнерам и блокам, когда я предоставляю учетные данные учетной записи. Я все еще не уверен, почему указанная политика не вернула правильные значения, но теперь она работает. Спасибо за ввод. – crunchy

3

Почему это?

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

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

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

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

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

+0

container.GetSharedAccessSignature (новый SharedAccessPolicy(), protected secureobolicy)) возвращает строку sas из контейнера (или, по крайней мере, это то, что я предполагаю, что я это делаю, я мог ошибаться.) – crunchy

+0

Geez, это было больно. По-видимому, я не получал тот же ключ, когда использовал метод GetSharedAccessSignature. Спасибо, что указал на Марка.Теперь мне просто нужно иметь дело с чувством дурака :) – crunchy

+1

Рад помочь - и не чувствую себя плохо - мы все это делаем! –

Смежные вопросы