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

使用托管身份从Azure VM访问Blob存储的后续步骤及认证问题

问题背景

已完成以下配置:

  • 为Azure VM启用了Azure托管身份
  • 授予VM访问Azure Blob存储的权限

现需明确访问Blob并列出目录的后续步骤,同时确认:

  1. 是否需要在VM上配置凭据?
  2. 仅通过Python代码直接访问是否必须使用CLI?

当前遇到的错误

使用ManagedIdentityCredential时的错误:

Listing directories in container: optitex
ImdsCredential.get_token_info failed: ManagedIdentityCredential authentication unavailable.
ManagedIdentityCredential.get_token_info failed: ManagedIdentityCredential authentication unavailable.

改用DefaultAzureCredential时的错误:

DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
ManagedIdentityCredential: ManagedIdentityCredential authentication unavailable.
SharedTokenCacheCredential: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential: Azure CLI not found on path
AzurePowerShellCredential: Az.Account module >= 2.2.0 is not installed
AzureDeveloperCliCredential: Azure Developer CLI could not be found.

使用的Python代码

from azure.storage.blob import BlobServiceClient
from azure.core.exceptions import ResourceNotFoundError
# 原代码遗漏身份验证类导入,需补充
from azure.identity import ManagedIdentityCredential, DefaultAzureCredential

# 列出容器内目录的函数
def list_directories_in_blob_container(storage_account_name, container_name):
    try:
        # 尝试使用托管身份凭据
        try:
            print('********')
            credential = ManagedIdentityCredential()
        except Exception as e:
            print(f"ManagedIdentityCredential失败: {e}")
            print("回退到DefaultAzureCredential")
            credential = DefaultAzureCredential()

        blob_service_client = BlobServiceClient(
            account_url=f"https://{storage_account_name}.blob.core.windows.net", 
            credential=credential
        )

        # 获取容器客户端
        container_client = blob_service_client.get_container_client(container_name)

        # 列出所有Blob并识别目录
        print(f"正在列出容器 {container_name} 中的目录:")
        blob_list = container_client.walk_blobs()

        directories = set()
        for blob in blob_list:
            blob_path_parts = blob.name.split('/')
            if len(blob_path_parts) > 1:
                directories.add(blob_path_parts[0])

        # 输出结果
        if directories:
            print("找到的目录:")
            for directory in sorted(directories):
                print(f" - {directory}")
        else:
            print("未找到目录。")

    except ResourceNotFoundError:
        print(f"存储账户 '{storage_account_name}' 中未找到容器 '{container_name}'。")
    except Exception as ex:
        print(f"发生错误: {ex}")

# 示例调用
if __name__ == "__main__":
    storage_account_name = "xxx"
    container_name = "xxx"
    list_directories_in_blob_container(storage_account_name, container_name)

解答

核心结论

  • 不需要额外配置CLI或环境变量:你已为VM启用系统托管身份并授予Blob访问权限,理论上直接通过托管身份即可完成验证。
  • 不需要在VM上手动配置凭据:托管身份会自动从Azure实例元数据服务(IMDS)获取令牌,无需手动配置任何凭据文件或环境变量。

后续步骤及问题排查

  1. 补充代码缺失的导入:原代码未导入ManagedIdentityCredential和DefaultAzureCredential,这是运行错误的直接原因之一,必须添加对应的导入语句。

  2. 排查托管身份未生效的原因

    • 确认VM的系统托管身份状态:在Azure门户的VM“身份”选项卡中,检查“系统分配”是否为“开启”状态。
    • 验证角色分配正确性:确保为VM托管身份分配了存储Blob数据读取者或更高权限的角色,且角色作用范围覆盖目标存储账户或容器。
    • 检查VM对IMDS的访问权限:在VM内部执行命令curl http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fstorage.azure.com/,如果无法返回令牌,说明NSG或其他网络策略限制了VM访问IMDS服务。
  3. 简化代码逻辑:无需手动切换凭据类型,直接使用DefaultAzureCredential即可,它会自动优先尝试托管身份验证,失败后才会尝试其他方式:

    credential = DefaultAzureCredential()
    

关于CLI的说明

仅通过Python代码访问Blob存储不需要使用CLI,CLI只是DefaultAzureCredential尝试的身份验证方式之一,并非必须配置。当托管身份正常工作时,DefaultAzureCredential会自动使用托管身份完成验证,无需依赖CLI。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:21:22