Ошибка: “Этот запрос не авторизован для выполнения данной операции” при использовании SASTokens для доступа к очередям Azure Storage с использованием Azure Storage SDK v12

Вопрос или проблема

Ошибка: “Этот запрос не авторизован для выполнения данной операции” при использовании SASTokens для доступа к очередям Azure Storage с использованием Azure Storage SDK v12

Я использую код C# (см. ниже) для чтения/добавления/обработки очередей Azure Storage с помощью Storage SDK v12 и SAS-токенов. Независимо от того, что я изменяю, я всегда получаю одну и ту же ошибку: “Этот запрос не авторизован для выполнения этой операции”.

Контекст:
Учётная запись хранилища существует, и у меня есть права владельца на неё.
Учётная запись хранилища НЕ защищена брандмауэром.
Этот же метод прекрасно работает для блобов/контейнеров в той же учётной записи хранилища.
Я могу делать всё, что хочу, с очередями из портала.

ПРИМЕЧАНИЕ: этот код (очень похожий) работает в производственном коде, который не имеет проблем при использовании MSI (тот же SDK v12) и/или без SAS-токенов (а с обычными ключами/строкой подключения).

Код:

string queueName = "queue1";
string accountName = "<account_name>";
string storageKey = "<account_key>";
string endpointSuffix = "core.windows.net";
string connectionString = $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={storageKey};EndpointSuffix={endpointSuffix}";

var options = new Azure.Storage.Queues.QueueClientOptions
{
    MessageEncoding = Azure.Storage.Queues.QueueMessageEncoding.Base64
};

Azure.Storage.Queues.QueueServiceClient serviceClient = new Azure.Storage.Queues.QueueServiceClient(
  serviceUri: new Uri($"https://{accountName}.queue.{endpointSuffix}"),
  credential: new Azure.Storage.StorageSharedKeyCredential(accountName, storageKey),
  options: options);

Azure.Storage.Queues.QueueClient client = serviceClient.GetQueueClient(queueName);

// client.CreateIfNotExistsAsync().Wait(); // **** Эта строка работает нормально - когда не закомментирована -, нет изменений в учётной записи хранилища

var queueSasBuilder = new QueueSasBuilder
{
    ExpiresOn = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(3)),
    QueueName = queueName
};

//  Определяет тип разрешения.
//var queueAccountPermissions = QueueAccountSasPermissions.Add | QueueAccountSasPermissions.Read | QueueAccountSasPermissions.Update | QueueAccountSasPermissions.Process;  //**** это также не срабатывает
//queueSasBuilder.SetPermissions(queueAccountPermissions);

var queuePermissions = QueueSasPermissions.Add | QueueSasPermissions.Read | QueueSasPermissions.Update | QueueSasPermissions.Process;
queueSasBuilder.SetPermissions(queuePermissions);

Uri sasUri = client.GenerateSasUri(queueSasBuilder);  // Клиент может сгенерировать SasUri

Uri partialUri = new Uri($"{sasUri.Scheme}://{sasUri.Host}{sasUri.AbsolutePath}");
Console.WriteLine($"SasToken для очереди хранилища успешно создан по uri: '{partialUri}', время истечения: '{queueSasBuilder.ExpiresOn}'");

client = new Azure.Storage.Queues.QueueClient(queueUri: sasUri);
client.CreateIfNotExistsAsync().Wait();  // *** Эта строка вызывает исключение

Я пробовал следующее:

  1. Раскомментировать эту строку:
// client.CreateIfNotExistsAsync().Wait(); // **** Эта строка работает нормально - когда не закомментирована -, нет изменений в учётной записи хранилища

И это работает нормально, то есть: не используя SAS-токены, всё работает.

  1. Раскомментировать эти две строки вместо использования QueueSasPermissions:
//var queueAccountPermissions = QueueAccountSasPermissions.Add | QueueAccountSasPermissions.Read | QueueAccountSasPermissions.Update | QueueAccountSasPermissions.Process;  //**** это также не срабатывает
//queueSasBuilder.SetPermissions(queueAccountPermissions);

Это тоже дает ту же ошибку.

  1. Я добавил роль StorageQueueDataContributor для моего принципала. Это также не сработало.

Ответ или решение

Ошибка "Этот запрос не авторизован для выполнения этой операции" при использовании SAS-токенов для доступа к очередям Azure Storage с помощью Azure Storage SDK v12 может возникать по нескольким причинам. Давайте разберем возможные причины и решения шаг за шагом.

1. Проверьте параметры SAS-токена

Убедитесь, что вы правильно устанавливаете параметры позволения (permissions) в вашем QueueSasBuilder. В вашем случае вы определяете следующие разрешения:

var queuePermissions = QueueSasPermissions.Add | QueueSasPermissions.Read | QueueSasPermissions.Update | QueueSasPermissions.Process;
queueSasBuilder.SetPermissions(queuePermissions);

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

2. Проверьте время истечения SAS-токена

Вы устанавливаете время истечения для SAS-токена:

ExpiresOn = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(3))

Убедитесь, что текущее время меньше времени истечения при создании токена. Если вы пытаетесь использовать токен через какое-то время, возможно, он уже вышел.

3. Проверьте создание SAS-токена

Обратите внимание, что SAS-токен необходимо генерировать с достаточными правами доступа к очереди, которая будет использоваться. Убедитесь, что вы вызываете GenerateSasUri после создания объекта QueueClient с полными разрешениями. Вы можете попробовать также вызвать client.GenerateSasUri(queueSasBuilder) до его использования.

4. Проблемы с синтаксисом

Ваш код на прямую вызывает метод CreateIfNotExistsAsync() на QueueClient, создаваемом с помощью SAS-токена:

client.CreateIfNotExistsAsync().Wait();  // *** Эта строка выдает исключение

Ваша цель – создание очереди, если она еще не существует. Однако если очередь уже существует с этими правами, вы можете получить ошибку. Попробуйте заменить эту строку на следующий код, чтобы увидеть, действительно ли очередь существует:

bool exists = await client.ExistsAsync();
if (!exists)
{
    await client.CreateAsync();
}
else
{
    Console.WriteLine("Очередь уже существует.");
}

5. Проверьте роли и разрешения

Убедитесь, что у вашей учетной записи или службы, которая генерирует SAS-токен, есть необходимые разрешения. Если вы используете роль Storage Queue Data Contributor, она должна давать право на создание очередей с использованием SAS-токенов, но если вы используете другой метод аутентификации (например, MSI), то это не всегда может быть аналогично.

6. Проверьте настройки хранилища

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

Заключение

Если после всех этих шагов проблема не решается, попробуйте создать SAS-токен для конкретной операции и просмотреть журналы Azure Storage для дополнительных сведений о том, почему запрос не был разрешен. Используйте диагностические инструменты и логи Azure для поиска источника проблемы.

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

Оцените материал
Добавить комментарий

Капча загружается...