You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python列出Blob遇AuthorizationPermissionMismatch错误,AZ CLI正常

问题描述

我有一个已存在的存储账户和容器,通过AZ CLI可以正常列出所有Blob:

[ ~ ]$ az storage blob list --account-name storageaccount20122022 --container-name test

There are no credentials provided in your command and environment, we will query for account key for your storage account.
It is recommended to provide --connection-string, --account-key or --sas-token in your command as credentials.

You also can add `--auth-mode login` in your command to use Azure Active Directory (Azure AD) for authorization if your login account is assigned required RBAC roles.
For more information about RBAC roles in storage, visit https://docs.microsoft.com/azure/storage/common/storage-auth-aad-rbac-cli.

In addition, setting the corresponding environment variables can avoid inputting credentials in your command. Please use --help to get more information about environment variable usage.
[
  {
    "container": "test",
    "content": "",
    ...
  }
]

我想用Python实现同样的功能,写了如下脚本:

import sys
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

def list_blobs_using_cli_credential(account_name, container_name):
    credential = DefaultAzureCredential()   # 也试过AzureCliCredential()
    blob_service_client = BlobServiceClient(
        account_url=f"https://{account_name}.blob.core.windows.net",
        credential=credential
    )
    container_client = blob_service_client.get_container_client(container_name)
    print(f"Listing blobs in {account_name}/{container_name} ...")
    try:
        blobs = container_client.list_blobs()
        for blob in blobs:
            print(blob.name)
    except Exception as e:
        print(f"Error listing blobs: {e}")

if __name__ == "__main__":
    account_name = sys.argv[1]
    container_name = sys.argv[2]
    list_blobs_using_cli_credential(account_name, container_name)

但在同一个Shell中运行该脚本时出现权限错误:

[ ~ ]$ python list-blobs.py storageaccount20122022 test
Listing blobs in storageaccount20122022/test ...
Error listing blobs: This request is not authorized to perform this operation using this permission.
RequestId:466b2647-201e-0022-13fd-918e18000000
Time:2024-04-19T01:59:22.6413231Z
ErrorCode:AuthorizationPermissionMismatch
Content: <?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:466b2647-201e-0022-13fd-918e18000000
Time:2024-04-19T01:59:22.6413231Z</Message></Error>

我能通过Python列出存储账户和容器,但无法对Blob执行任何操作(列出、删除、上传),而AZ CLI却能正常执行。我在两个完全独立的Azure账户中测试过,其中一个账户我是所有者,但问题依旧。

请问:

  1. AZ CLI是如何自动获取权限执行Blob操作的?
  2. 如何在Python代码中实现相同的功能?

解答

一、AZ CLI自动获取权限的方式

当你没有在az storage blob list命令中指定凭证(连接字符串、账户密钥、SAS令牌)时,AZ CLI会按优先级尝试以下两种授权方式:

  1. 优先获取存储账户密钥:CLI调用Azure管理API读取目标存储账户的账户密钥,然后用该密钥进行Shared Key授权。这种方式不需要Blob相关的RBAC权限,只要你的登录账户有读取存储账户密钥的权限(比如Storage Account Contributor或更高权限,所有者角色包含此权限)就能生效。
  2. 回退到Azure AD授权:如果无法获取账户密钥,CLI才会尝试用当前登录的Azure AD身份授权,这时候需要你的账户被分配Blob数据相关的RBAC角色(比如Storage Blob Data Reader)。

你看到的CLI输出提示已经明确说明了这个逻辑,这也是你作为所有者能正常操作的原因——所有者权限允许读取存储账户密钥,进而完成Blob操作的授权。

二、Python代码实现相同功能的方法

你的Python脚本使用的是Azure AD身份授权,但仅仅是账户所有者并不自动拥有Blob数据的操作权限(所有者是管理层面角色,而非数据层面)。要实现和CLI一致的行为,有两种可选方案:

方案1:模拟CLI优先使用账户密钥的逻辑

通过Azure管理API获取存储账户密钥,再用该密钥初始化BlobServiceClient:

import sys
from azure.identity import DefaultAzureCredential
from azure.mgmt.storage import StorageManagementClient
from azure.storage.blob import BlobServiceClient

def list_blobs_using_account_key(account_name, container_name, subscription_id, resource_group_name):
    # 获取存储账户密钥
    credential = DefaultAzureCredential()
    storage_client = StorageManagementClient(credential, subscription_id)
    keys = storage_client.storage_accounts.list_keys(resource_group_name, account_name)
    account_key = keys.keys[0].value

    # 用账户密钥初始化BlobServiceClient
    blob_service_client = BlobServiceClient(
        account_url=f"https://{account_name}.blob.core.windows.net",
        credential=account_key
    )
    container_client = blob_service_client.get_container_client(container_name)
    
    print(f"Listing blobs in {account_name}/{container_name} ...")
    try:
        blobs = container_client.list_blobs()
        for blob in blobs:
            print(blob.name)
    except Exception as e:
        print(f"Error listing blobs: {e}")

if __name__ == "__main__":
    account_name = sys.argv[1]
    container_name = sys.argv[2]
    subscription_id = sys.argv[3]
    resource_group_name = sys.argv[4]
    list_blobs_using_account_key(account_name, container_name, subscription_id, resource_group_name)

方案2:给账户分配Blob数据RBAC角色

如果你想继续使用Azure AD身份授权,需要给登录账户分配Blob数据相关的RBAC角色,比如:

  • Storage Blob Data Reader:仅允许读取Blob
  • Storage Blob Data Contributor:允许读写Blob

分配范围可以是存储账户、容器或资源组。角色分配生效后(通常需要几分钟),你的原Python脚本就能正常执行Blob操作。


内容的提问来源于stack exchange,提问作者MLu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:55:59