如何通过工作负载身份从AKS访问Azure Cosmos DB for MongoDB
问题
已完成AKS OIDC启用、用户分配托管身份(test-mongo)创建、ServiceAccount与联邦身份凭证配置,但Python应用无法通过工作负载身份访问Azure Cosmos DB for MongoDB:
- 初始代码因
get_token()缺少scope报错 - 使用SQL API的
CosmosClient时,因MongoDB API不支持SQL RBAC角色导致权限不足 - 指定scope获取token拼接连接字符串时,触发"Invalid key"认证失败
正确实现步骤
1. 为托管身份分配正确的Cosmos DB角色
MongoDB API的Cosmos DB不支持SQL API的RBAC角色体系,需分配Cosmos DB内置的MongoDB专属角色,常用选项:
MongoDB Data Reader:只读权限MongoDB Data Contributor:读写权限Cosmos DB Account Reader Role:账户级只读权限
使用Azure CLI完成角色分配(替换占位符):
az cosmosdb mongodb role assignment create \ --account-name <cosmosdb-account-name> \ --resource-group <resource-group-name> \ --role-definition-name "MongoDB Data Contributor" \ --principal-id <managed-identity-principal-id> \ --database-name "*" \ --collection-name "*"
2. 修正Python代码
核心要点:
- 使用Cosmos DB通用scope:
https://cosmos.azure.com/.default - 对token进行URL编码,避免特殊字符破坏连接字符串解析
- 明确指定MongoDB认证机制
from azure.identity import DefaultAzureCredential from pymongo import MongoClient import urllib.parse def main(): # 指定托管身份客户端ID,确保触发工作负载身份认证 credential = DefaultAzureCredential( managed_identity_client_id="<my-user-assigned-managed-identity-app-id>" ) # 获取符合MongoDB API要求的访问token token = credential.get_token("https://cosmos.azure.com/.default").token # URL编码token,解决特殊字符导致的"Invalid key"问题 encoded_token = urllib.parse.quote_plus(token) # 拼接标准MongoDB连接字符串 cosmos_account = "<cosmosdb-account-name>" connection_string = ( f"mongodb://{cosmos_account}:{encoded_token}@{cosmos_account}.mongo.cosmos.azure.com:10255/" "?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000" f"&appName=@{cosmos_account}@&authMechanism=SCRAM-SHA-256&authSource=admin" ) client = MongoClient(connection_string) # 验证连接有效性 print("可用数据库:", client.list_database_names()) if __name__ == "__main__": main()
过往错误原因说明
- 方案1(CosmosClient)失败:
CosmosClient是SQL API专属客户端,MongoDB API不兼容SQL API的RBAC角色体系,因此无法完成认证。 - 方案2(指定scope)失败:
- 使用了错误的scope:
https://<account>.documents.azure.com/.default是SQL API专属scope,MongoDB API需用通用的https://cosmos.azure.com/.default - 未对token编码:token包含
+、/、=等特殊字符,直接放入连接字符串会被解析为无效密钥
- 使用了错误的scope:
内容的提问来源于stack exchange,提问作者Laurent Michel
相关产品推荐
相关产品推荐

