Search code examples
.netazureazure-blob-storagemessage-queueshared-access-signatures

Insert message in Azure Queue using Service SAS Token


This is my first time working with SAS. I am trying to access the azure queues using Service Sas Token and trying to insert a message but it is not working. When I try to access the generated URI from browser then I am getting below error

"The resource doesn't support specified Http Verb. RequestId:cc1f2356-f003-0015-78b6-15f337000000 Time:2023-11-12T22:23:52.3942771Z". What could be the problem? Below is my sample code

Note: I will replace queueName, AccountName and AccountKey with original values.

public async Task<ApiResponse<BlobServiceClient>> GetServiceQueueSasToken()
{
ApiResponse<BlobServiceClient> result = new ApiResponse<BlobServiceClient>();
try
{

string queueName = "queueName";
string accountName = "accountName";
string accountKey = "accountKey";
StorageSharedKeyCredential storageSharedKeyCredential = new(accountName, accountKey);

var serviceQueueUri = new Uri($"https://{accountName}.queue.core.windows.net/{queueName}");
string sasToken = await CreateServiceQueueSASToken(storageSharedKeyCredential, queueName);
BlobServiceClient blobServiceClientAccountSAS = new BlobServiceClient(new Uri($"{serviceQueueUri}?  {sasToken}"));

SendMessageUsingSasToken(blobServiceClientAccountSAS.Uri queueName, sasToken);

result.Data = blobServiceClientAccountSAS;
result.IsSucceed = true;
}
catch (Exception ex)
{
result.IsSucceed = false;
result.Exception = ex;
result.ErrorMessages = new List<string>();
result.ErrorMessages.Add(ex.Message);
}
return result;
}

public static async Task<string> CreateServiceQueueSASToken(StorageSharedKeyCredential sharedKey, string   queueName)
{
 var queueSasBuilder = new QueueSasBuilder()
 {
 QueueName = queueName,
 ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
 Protocol = SasProtocol.Https
 };

queueSasBuilder.SetPermissions(QueueSasPermissions.Add | QueueSasPermissions.Read);

string sasToken = queueSasBuilder.ToSasQueryParameters(sharedKey).ToString();

return sasToken;
}

static void SendMessageUsingSasToken(Uri serviceUri, string queueName, string sasToken)
{
 var queueClient = new QueueClient(serviceUri, queueName, sasToken);
 queueClient.SendMessage("Your message content", sasToken);
 Console.WriteLine("Message sent successfully.");
}

Solution

  • The issue with using the SAS token in your SendMessageUsingSasToken method. The QueueClient constructor already expects the SAS token to be included in the URI, so you don't need to pass it again as a parameter when creating the QueueClient.

    The code below generates a Shared Access Signature (SAS) token for an Azure Storage Queue and uses it to send a message to the specified queue.

    
    using Azure.Storage;
    using Azure.Storage.Queues;
    using Azure.Storage.Sas;
    using Azure.Storage.Shared;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    public class ApiResponse<T>
    {
        public T Data { get; set; } = default!;
        public bool IsSucceed { get; set; }
        public Exception? Exception { get; set; }
        public List<string> ErrorMessages { get; set; } = new List<string>();
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var response = GetServiceQueueSasToken().Result; // Blocking call
            if (response.IsSucceed)
            {
                Console.WriteLine("SAS token generated successfully.");
            }
            else
            {
                Console.WriteLine($"Error: {response.Exception?.Message}");
            }
        }
    
        public static async Task<ApiResponse<QueueServiceClient>> GetServiceQueueSasToken()
        {
            ApiResponse<QueueServiceClient> result = new ApiResponse<QueueServiceClient>();
            try
            {
                string queueName = "AzurequeueName";
                string accountName = "AzureStorageAccountName ";
                string accountKey = "AzureStorageAccountAccountKey";
    
                StorageSharedKeyCredential storageSharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
    
                var serviceQueueUri = new Uri($"https://{accountName}.queue.core.windows.net");
                string sasToken = CreateServiceQueueSASToken(storageSharedKeyCredential, queueName);
    
                QueueServiceClient queueServiceClient = new QueueServiceClient(new Uri($"{serviceQueueUri}?{sasToken}"));
    
                SendMessageUsingSasToken(queueServiceClient, queueName);
    
                result.Data = queueServiceClient;
                result.IsSucceed = true;
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Exception = ex;
                result.ErrorMessages = new List<string> { ex.Message };
            }
            return result;
        }
    
        public static string CreateServiceQueueSASToken(StorageSharedKeyCredential sharedKey, string queueName)
        {
            var queueSasBuilder = new QueueSasBuilder
            {
                QueueName = queueName,
                ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
                Protocol = SasProtocol.Https
            };
    
            queueSasBuilder.SetPermissions(QueueSasPermissions.Add | QueueSasPermissions.Read);
    
            string sasToken = queueSasBuilder.ToSasQueryParameters(sharedKey).ToString();
    
            return sasToken;
        }
    
        static void SendMessageUsingSasToken(QueueServiceClient queueServiceClient, string queueName)
        {
            var queueClient = queueServiceClient.GetQueueClient(queueName);
            queueClient.SendMessage("Your message content");
            Console.WriteLine("Message sent successfully.");
        }
    }
    
    

    Output:

    enter image description here

    enter image description here