窥视 azure 存储消息队列因 python 而失败,但可以通过门户工作

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

我正在尝试使用 python 以编程方式访问存储队列,但查看消息失败并出现身份验证错误:

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

我的代码如下所示:

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

请注意,存储帐户是通过 Terraform 创建的,没有特殊配置

根据您提供的代码,您希望使用 Azure AD 令牌查看 Azure 队列存储中的消息。如果是这样,您需要分配一些特殊的 Azure RABC 角色(Storage Queue Data ContributorStorage Queue Data Reader and Storage Queue Data Message Processor) 给用于登录 Azure CLI 的用户或服务主体。详情请参考here and here.

例如

  1. Storage Queue Data Reader 角色分配给用户或服务主体
az role assignment create \
    --role "Storage Queue Data Reader" \
    --assignee <email> \
    --scope "/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"
  1. 注销并使用 Azure CLI 重新登录
az logout
az login
az account set -s '<your subscription Id >'
  1. 代码
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)