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

通过托管身份从Azure App Service访问CosmosDB失败求助

问题:FastAPI部署Azure App Service后,用托管身份访问CosmosDB报错Unrecognized credential type

已执行操作步骤

步骤1:Terraform配置托管身份与角色分配

通过Terraform为Azure App Service配置系统分配托管身份,并为该身份分配CosmosDB的Contributor角色,代码如下:

resource "azurerm_linux_web_app" "this" {
  name                = var.appname
  location            = var.location
  resource_group_name = var.rg_name
  service_plan_id     = azurerm_service_plan.this.id

  app_settings = {
    "PROD"                               = false
    "DOCKER_ENABLE_CI"                   = true
    "DOCKER_REGISTRY_SERVER_URL"         = data.azurerm_container_registry.this.login_server
    "WEBSITE_HTTPLOGGING_RETENTION_DAYS" = "30"
    "WEBSITE_ENABLE_APP_SERVICE_STORAGE" = false
  }

  lifecycle {
    ignore_changes = [
      app_settings["WEBSITE_HTTPLOGGING_RETENTION_DAYS"]
    ]
  }

  https_only = true
  
  identity {
    type = "SystemAssigned"
  }
}

data "azurerm_cosmosdb_account" "this" {
  name                = var.cosmosdb_account_name
  resource_group_name = var.cosmosdb_resource_group_name
}

// 为App Service分配CosmosDB读写权限的内置角色
resource "azurerm_role_assignment" "cosmosdbContributor" {
  scope                = data.azurerm_cosmosdb_account.this.id
  principal_id         = azurerm_linux_web_app.this.identity.0.principal_id
  role_definition_name = "Contributor"
}

步骤2:Python代码中使用托管身份认证

尝试通过ManagedIdentityCredential初始化CosmosDB客户端,代码片段:

from azure.identity import ManagedIdentityCredential
from azure.cosmos.cosmos_client import CosmosClient

client = CosmosClient(get_endpoint(), credential=ManagedIdentityCredential())
client = self._get_or_create_client()
database = client.get_database_client(DB_NAME)
container = database.get_container_client(CONTAINER_NAME)
container.query_items(query) 

错误信息

本地及Azure App Service环境运行均触发以下错误:

raise TypeError(
TypeError: Unrecognized credential type. Please supply the master key as str, or a dictionary or resource tokens, or a list of permissions.

解决方案

1. 适配CosmosDB SDK的认证方式

旧版azure.cosmos SDK(版本<4.0)不支持直接传入ManagedIdentityCredential对象,需要先获取Azure AD访问令牌,再将令牌作为凭证传入:

from azure.identity import ManagedIdentityCredential
from azure.cosmos import CosmosClient

# 获取CosmosDB的Azure AD访问令牌
credential = ManagedIdentityCredential()
token = credential.get_token("https://cosmos.azure.com/.default").token

# 使用令牌初始化客户端
client = CosmosClient(get_endpoint(), credential=token)

# 后续数据操作保持不变
database = client.get_database_client(DB_NAME)
container = database.get_container_client(CONTAINER_NAME)
container.query_items(query)

2. 优化角色分配

  • 替换Contributor角色为Cosmos DB Built-in Data Contributor,该角色是专门为CosmosDB数据读写设计的内置角色,权限更精准,避免过度授权。
  • 确认角色分配已生效:Azure RBAC权限同步可能需要1-5分钟,可在Azure门户的CosmosDB账户「访问控制(IAM)」页面查看分配状态。

3. 本地测试配置

本地运行时,需确保已通过Azure CLI登录(执行az login),或者设置AZURE_CLIENT_ID环境变量(若使用用户分配托管身份),让ManagedIdentityCredential能获取有效令牌。

4. 验证App Service托管身份状态

在Azure门户的App Service「标识」页面,确认系统分配身份已启用,且状态为「已启用」。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:15:26