使用系统分配托管标识在Azure VM上通过Python列出Blob失败
我尝试通过Python代码列出Azure存储容器中的所有Blob,代码如下:
import io import os from azure.core.exceptions import HttpResponseError, ResourceExistsError from azure.identity import DefaultAzureCredential from msrestazure.azure_active_directory import MSIAuthentication from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient, BlobLeaseClient, BlobPrefix, ContentSettings class BlobSamples(object): # <Snippet_list_blobs_flat> def list_blobs_flat(self, blob_service_client: BlobServiceClient, container_name): container_client = blob_service_client.get_container_client(container=container_name) blob_list = container_client.list_blobs() for blob in blob_list: print(f"Name: {blob.name}") # </Snippet_list_blobs_flat> if __name__ == '__main__': # TODO: Replace <storage-account-name> with your actual storage account name account_url = "https://testinglist.blob.core.windows.net" credential = DefaultAzureCredential() # Create the BlobServiceClient object blob_service_client = BlobServiceClient(account_url, credential=credential) sample = BlobSamples() sample.list_blobs_flat(blob_service_client, "testing")
这段代码在带有系统分配托管标识的虚拟机上运行,执行时出现以下错误:
Traceback (most recent call last): File "listblob.py", line 28, in <module> sample.list_blobs_flat(blob_service_client, "testing") File "listblob.py", line 15, in list_blobs_flat for blob in blob_list: File "/usr/local/lib/python3.6/site-packages/azure/core/paging.py", line 128, in __next__ return next(self._page_iterator) File "/usr/local/lib/python3.6/site-packages/azure/core/paging.py", line 76, in __next__ self._response = self._get_next(self.continuation_token) File "/usr/local/lib/python3.6/site-packages/azure/storage/blob/_list_blobs_helper.py", line 83, in _get_next_cb process_storage_error(error) File "/usr/local/lib/python3.6/site-packages/azure/storage/blob/_shared/response_handlers.py", line 181, in process_storage_error exec("raise error from None") # pylint: disable=exec-used # nosec File "<string>", line 1, in <module> azure.core.exceptions.HttpResponseError: This request is not authorized to perform this operation using this permission. RequestId:32c35c2b-101e-0066-801f-932ff0000000 Time:2023-05-30T17:55:50.1950002Z 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:32c35c2b-101e-0066-801f-932ff0000000 Time:2023-05-30T17:55:50.1950002Z</Message></Error>
容器为私有容器,但已允许所有网络访问,无法定位问题,需要协助解决。
解决步骤
1. 确认托管标识的角色分配(核心问题)
Azure存储的数据平面操作(如列出Blob)需要专门的数据角色权限,普通的管理角色(如“读者”)无法访问Blob数据。必须为虚拟机的系统分配托管标识添加以下角色:
- 存储Blob数据读取者(Storage Blob Data Reader)
操作流程:
- 登录Azure门户,找到目标存储账户
- 进入「访问控制(IAM)」→「添加」→「添加角色分配」
- 在角色列表中搜索并选择「存储Blob数据读取者」
- 在「成员」选项卡中,选择「托管标识」→「选择成员」,找到对应虚拟机的系统分配标识并添加
- 完成角色分配保存
2. 验证角色分配的范围
确保角色分配的范围覆盖目标资源:
- 可以直接将角色分配到存储账户级别(覆盖所有容器),或者特定容器级别(仅授权目标容器)
- 避免仅将角色分配到资源组级别,除非存储账户确实在该资源组内且权限继承正常
3. 等待权限生效
Azure角色分配通常需要5-10分钟才能完全生效,完成分配后请等待一段时间再测试代码。
4. 在虚拟机上验证托管标识权限
可以通过Azure CLI在虚拟机上直接测试权限是否正常:
# 使用系统托管标识登录 az login --identity # 列出目标容器的Blob az storage blob list --account-name testinglist --container-name testing --auth-mode login
如果该命令执行成功,说明权限配置正确,问题可能出在代码环境;如果同样报错,继续检查角色分配。
5. 检查代码中的凭证配置
代码中使用DefaultAzureCredential是正确的,在带有系统分配托管标识的VM上,它会自动优先使用MSI凭证。如果虚拟机上存在其他凭证(如环境变量中的账户密钥),可能会干扰凭证选择,可以尝试直接指定使用MSI凭证来排除问题:
from azure.identity import ManagedIdentityCredential # 改用ManagedIdentityCredential直接调用系统托管标识 credential = ManagedIdentityCredential()
内容的提问来源于stack exchange,提问作者user2916639
相关产品推荐
相关产品推荐

