Skip to main content
added some code comments
Source Link
var serviceQueueClient = new QueueClient(GetServiceSasToken());
return await serviceQueueClient.ExistsAsync(); // this line throws the exception

private Uri GetServiceSasToken()
{
    var queueSasBuilder = new QueueSasBuilder()
    {
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        QueueName = _queueName, // Name of my queue, which exists on Azure Portal
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(QueueSasPermissions.Read | QueueSasPermissions.Add | QueueSasPermissions.Process);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
var serviceQueueClient = new QueueClient(GetAccountSasToken());
return await serviceQueueClient.ExistsAsync(); // this line throws the exception

private Uri GetAccountSasToken()
{
    var queueSasBuilder = new AccountSasBuilder()
    {
        Services = AccountSasServices.Queues,
        ResourceTypes = AccountSasResourceTypes.Service | AccountSasResourceTypes.Container | AccountSasResourceTypes.Object,
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(AccountSasPermissions.Create | AccountSasPermissions.List | AccountSasPermissions.Read);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
var serviceQueueClient = new QueueClient(GetServiceSasToken());
return await serviceQueueClient.ExistsAsync();

private Uri GetServiceSasToken()
{
    var queueSasBuilder = new QueueSasBuilder()
    {
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        QueueName = _queueName, // Name of my queue, which exists on Azure Portal
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(QueueSasPermissions.Read | QueueSasPermissions.Add | QueueSasPermissions.Process);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
var serviceQueueClient = new QueueClient(GetAccountSasToken());
return await serviceQueueClient.ExistsAsync();

private Uri GetAccountSasToken()
{
    var queueSasBuilder = new AccountSasBuilder()
    {
        Services = AccountSasServices.Queues,
        ResourceTypes = AccountSasResourceTypes.Service | AccountSasResourceTypes.Container | AccountSasResourceTypes.Object,
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(AccountSasPermissions.Create | AccountSasPermissions.List | AccountSasPermissions.Read);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
var serviceQueueClient = new QueueClient(GetServiceSasToken());
return await serviceQueueClient.ExistsAsync(); // this line throws the exception

private Uri GetServiceSasToken()
{
    var queueSasBuilder = new QueueSasBuilder()
    {
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        QueueName = _queueName, // Name of my queue, which exists on Azure Portal
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(QueueSasPermissions.Read | QueueSasPermissions.Add | QueueSasPermissions.Process);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
var serviceQueueClient = new QueueClient(GetAccountSasToken());
return await serviceQueueClient.ExistsAsync(); // this line throws the exception

private Uri GetAccountSasToken()
{
    var queueSasBuilder = new AccountSasBuilder()
    {
        Services = AccountSasServices.Queues,
        ResourceTypes = AccountSasResourceTypes.Service | AccountSasResourceTypes.Container | AccountSasResourceTypes.Object,
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(AccountSasPermissions.Create | AccountSasPermissions.List | AccountSasPermissions.Read);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}
Source Link

Checking if an Azure Storage Queue exists

I would like to check if an Azure Storage Queue exists by calling the Azure.Storage.Queues.ExistsAsync(CancellationToken cancellationToken = default) method within the Azure Storage v12 API. I am trying to do this via SAS tokens as per business requirements, but I am getting an authorization error as below:

Azure.RequestFailedException: This request is not authorized to perform this operation.
Status: 403 
ErrorCode: AuthorizationFailure

In the stack trace I can see that this line throws the error within the API:

Azure.Storage.Queues.QueueRestClient.GetPropertiesAsync(Nullable`1 timeout, CancellationToken cancellationToken)

I am using the API as shown below:

var serviceQueueClient = new QueueClient(GetServiceSasToken());
return await serviceQueueClient.ExistsAsync();

private Uri GetServiceSasToken()
{
    var queueSasBuilder = new QueueSasBuilder()
    {
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        QueueName = _queueName, // Name of my queue, which exists on Azure Portal
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(QueueSasPermissions.Read | QueueSasPermissions.Add | QueueSasPermissions.Process);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}

I have also tried using an Account SAS token as below, but this also fails with the same error.

var serviceQueueClient = new QueueClient(GetAccountSasToken());
return await serviceQueueClient.ExistsAsync();

private Uri GetAccountSasToken()
{
    var queueSasBuilder = new AccountSasBuilder()
    {
        Services = AccountSasServices.Queues,
        ResourceTypes = AccountSasResourceTypes.Service | AccountSasResourceTypes.Container | AccountSasResourceTypes.Object,
        ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15),
        Protocol = SasProtocol.Https
    };

    queueSasBuilder.SetPermissions(AccountSasPermissions.Create | AccountSasPermissions.List | AccountSasPermissions.Read);
    StorageSharedKeyCredential storageSharedKeyCredential = new(_accountName, _accountKey); // storage account name, and the access key
    var sasQueryParams = queueSasBuilder.ToSasQueryParameters(storageSharedKeyCredential).ToString();
    return new UriBuilder()
    {
        Scheme = "https",
        Host = $"{_accountName}.queue.core.windows.net",
        Path = _queueName,
        Query = sasQueryParams
    }.Uri;
}

I managed to manipulate Azure Blobs in a similar way within the same kubernetes pod, so the private endpoint should be working okay in my environment. What am I missing?