我正在使用类似这样的 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
我尝试过以下方法:
// client.CreateIfNotExistsAsync().Wait(); // **** This line works fine -when not commented-, no change in the storage account
并且它工作正常,即:不使用 SAS 令牌也可以工作
//var queueAccountPermissions = QueueAccountSasPermissions.Add | QueueAccountSasPermissions.Read | QueueAccountSasPermissions.Update | QueueAccountSasPermissions.Process; //**** this fails the same way
//queueSasBuilder.SetPermissions(queueAccountPermissions);
它失败并出现同样的错误。
使用 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.