Search code examples
pythonazure-storageazure-storage-queues

Peeking azure storage message queue fails with python but works through the portal


I am trying to access a storage queue programatically with python but peeking at the messages fails with an Auth error:

azure.core.exceptions.HttpResponseError: This request is not authorized to perform this operation using this permission.
RequestId:xxxx
Time:2020-12-10T08:03:46.1919000Z
ErrorCode:AuthorizationPermissionMismatch
Error:None

My code looks like this:

from azure.storage.queue import (
    QueueClient, TextBase64DecodePolicy
)
from azure.identity import AzureCliCredential

credential = AzureCliCredential()
DEFAULT_SUBSCRIPTION_ID = "xxx"
DEFAULT_POISON_QUEUE_NAME = "webjobs-blobtrigger-poison"
storage_account_name = "stxxx"

url = f"https://{storage_account_name}.queue.core.windows.net/{DEFAULT_POISON_QUEUE_NAME}"
client = QueueClient.from_queue_url(url, credential, message_decode_policy=TextBase64DecodePolicy())

properties = queue_client.get_queue_properties() 
count = properties.approximate_message_count # works?!?

messages = queue_client.peek_messages(count) # exception

Note the storage account was created through terraform and has no special config


Solution

  • According to the code you provide, you want to use Azure AD token to peek messages from Azure queue storage. If so, you need to assign some special Azure RABC role(Storage Queue Data Contributor, Storage Queue Data Reader and Storage Queue Data Message Processor) to the user or service principal you use to login in Azure CLI. For more details, please refer to here and here.

    For example

    1. Assign Storage Queue Data Reader role to the user or service principal
    az role assignment create \
        --role "Storage Queue Data Reader" \
        --assignee <email> \
        --scope "/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"
    
    1. Sign out and log in again with Azure CLI
    az logout
    az login
    az account set -s '<your subscription Id >'
    
    1. code
    from azure.storage.queue import QueueClient, TextBase64DecodePolicy
    from azure.identity import AzureCliCredential
    
    credential = AzureCliCredential()
    
    DEFAULT_POISON_QUEUE_NAME = "myqueue"
    storage_account_name = "andyprivate"
    
    url = f"https://{storage_account_name}.queue.core.windows.net/{DEFAULT_POISON_QUEUE_NAME}"
    client = QueueClient.from_queue_url(
        url, credential, message_decode_policy=TextBase64DecodePolicy())
    
    properties = client .get_queue_properties()
    count = properties.approximate_message_count  
    print(count)
    messages = client.peek_messages(count)  
    for message in messages:
        print("Message: " + message.content)
    

    enter image description here