使用 Azure 存储 SDK v12 使用 SASToken 访问 Azure 存储队列时出现错误:“此请求无权执行此操作”

问题描述 投票:0回答:1

我正在使用类似这样的 C# 代码(见下文)来使用 Storage SDK v12 和 SAS 令牌读取/添加/处理 Azure 存储队列。无论我更改什么,我总是遇到相同的错误:“此请求无权执行此操作”

背景: 存储帐户存在,并且我拥有其所有者权限。 存储帐户没有防火墙保护。 同样的方法对于同一存储帐户上的 blob/容器效果很好。 我可以在门户的队列中做任何我想做的事情。

注意:此代码(非常相似)正在归档到生产代码中,在使用 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(); // **** This line works fine -when not commented-, no change in the storage account

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

//  Defines the type of permission.
//var queueAccountPermissions = QueueAccountSasPermissions.Add | QueueAccountSasPermissions.Read | QueueAccountSasPermissions.Update | QueueAccountSasPermissions.Process;  //**** this fails the same way
//queueSasBuilder.SetPermissions(queueAccountPermissions);

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

Uri sasUri = client.GenerateSasUri(queueSasBuilder);  // The client can generate the SasUri

Uri partialUri = new Uri($"{sasUri.Scheme}://{sasUri.Host}{sasUri.AbsolutePath}");
Console.WriteLine($"Successfully created SasToken storage queue for uri: '{partialUri}', expiration time: '{queueSasBuilder.ExpiresOn}'");

client = new Azure.Storage.Queues.QueueClient(queueUri: sasUri);
client.CreateIfNotExistsAsync().Wait();  // *** This line throws the exception

我尝试过以下方法:

  1. 取消注释此行:
// client.CreateIfNotExistsAsync().Wait(); // **** This line works fine -when not commented-, no change in the storage account

并且它工作正常,即:不使用 SAS 令牌也可以工作

  1. 取消注释这两行,而不是使用 QueueSasPermissions:
//var queueAccountPermissions = QueueAccountSasPermissions.Add | QueueAccountSasPermissions.Read | QueueAccountSasPermissions.Update | QueueAccountSasPermissions.Process;  //**** this fails the same way
//queueSasBuilder.SetPermissions(queueAccountPermissions);

它失败并出现同样的错误。

  1. 我为我的主体添加了 RoleAssignment StorageQueueDataContributor。同样失败。
azure-storage-queues sas-token
1个回答
0
投票

使用 Azure 存储 SDK v12 使用 SASToken 访问 Azure 存储队列时出现错误:“此请求无权执行此操作”

为了确保是否创建azure存储队列,您需要在代码中使用azure存储

account sas

您可以使用以下代码创建帐户 sas 令牌并检查 azure 队列是否已创建以及它使用 Azure 存储 .Net SDK 发送消息。

代码:

using Azure.Storage;
using Azure.Storage.Queues;
using Azure.Storage.Sas;
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            await GetServiceQueueSasToken();
            Console.WriteLine("SAS token generated and message sent successfully.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }

    public static async Task GetServiceQueueSasToken()
    {
        // Storage account details
        string accountName = "venkat326123";
        string accountKey = "T3xxxxxw==";
        string queueName ="queue2";
        string sasToken = CreateAccountSasToken(accountName, accountKey);
        var serviceUri = new Uri($"https://{accountName}.queue.core.windows.net?{sasToken}");
        var queueServiceClient = new QueueServiceClient(serviceUri);
        await EnsureQueueExists(queueServiceClient, queueName);
        SendMessage(queueServiceClient, queueName);
    }
    public static string CreateAccountSasToken(string accountName, string accountKey)
    {
        var sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
        // Create Account SAS
        AccountSasBuilder sasBuilder = new AccountSasBuilder
        {
            ExpiresOn = DateTimeOffset.UtcNow.AddHours(1), // Set expiration time
            Services = AccountSasServices.Queues,         // Enable queue service
            ResourceTypes = AccountSasResourceTypes.Service | AccountSasResourceTypes.Container | AccountSasResourceTypes.Object, 
        };

        // Set permissions for queue operations
        sasBuilder.SetPermissions(AccountSasPermissions.Add | AccountSasPermissions.Create | AccountSasPermissions.Read | AccountSasPermissions.Write);
        string sasToken = sasBuilder.ToSasQueryParameters(sharedKeyCredential).ToString();
        return sasToken;
    }

    public static async Task EnsureQueueExists(QueueServiceClient queueServiceClient, string queueName)
    {
        var queueClient = queueServiceClient.GetQueueClient(queueName);
        var createResult = await queueClient.CreateIfNotExistsAsync();
        if (createResult != null)
        {
            Console.WriteLine($"Queue '{queueName}' created.");
        }
        else
        {
            Console.WriteLine($"Queue '{queueName}' already exists.");
        }
    }

    public static void SendMessage(QueueServiceClient queueServiceClient, string queueName)
    {
        var queueClient = queueServiceClient.GetQueueClient(queueName);
        queueClient.SendMessage("Hello, Azure Queue with SAS!");
        Console.WriteLine("Message sent successfully.");
    }
}

输出:

Queue 'queue2' already exists.
Message sent successfully.
SAS token generated and message sent successfully.

enter image description here

参考: 使用 .NET 创建帐户 SAS - Azure 存储 |微软学习

© www.soinside.com 2019 - 2024. All rights reserved.