使用主键调用CosmosDB List Permissions REST API遇授权错误求修正
问题根源分析
从服务器返回的签名payload来看,核心问题集中在签名验证不匹配,具体可能是以下几点:
- 资源路径不一致:你的请求URL中数据库ID是
MyDatabaseID,但服务器生成的payload里是dbs/CosmosDBSql1/users/VinnyG,说明代码中构造签名的资源路径和实际请求的URL路径不匹配。 - payload格式错误:签名payload必须严格遵循
HTTP方法\n资源类型\n资源路径\n日期\n\n的格式,末尾必须保留一个空行,任何换行、空格、大小写偏差都会导致签名验证失败。 - 日期格式不符合要求:必须使用小写的RFC1123格式(如
fri, 30 dec 2022 22:08:00 gmt),且请求头的x-ms-date必须和签名payload中的日期完全一致。 - 主键处理错误:CosmosDB主键是Base64编码字符串,生成签名前需要先解码为字节数组,再通过HMAC-SHA256算法计算签名。
修正后的Python示例代码
import hmac import hashlib import base64 import requests from datetime import datetime, timezone # 配置参数 account_name = "mynosqlaccount" database_id = "MyDatabaseID" # 必须和URL中的数据库ID完全一致 user_id = "VinnyG" primary_key = "<你的CosmosDB主键>" resource_type = "permissions" http_method = "get" # 构造签名用的资源路径:对应URL中dbs/{db-id}/users/{user-id}部分 resource_path = f"dbs/{database_id}/users/{user_id}" # 生成符合要求的UTC日期(小写RFC1123格式) date = datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S %Z").lower() # 构造签名payload:严格遵循格式,末尾必须保留空行 payload = f"{http_method}\n{resource_type}\n{resource_path}\n{date}\n\n" # 解码主键为字节数组 key_bytes = base64.b64decode(primary_key) # 计算HMAC-SHA256签名并Base64编码 signature = hmac.new(key_bytes, payload.encode("utf-8"), hashlib.sha256).digest() signature_base64 = base64.b64encode(signature).decode("utf-8") # 构造授权头 auth_header = f"type=master&ver=1.0&sig={signature_base64}" # 构造请求URL url = f"https://{account_name}.documents.azure.com/{resource_path}/{resource_type}" # 发送请求 headers = { "x-ms-date": date, "Authorization": auth_header, "x-ms-version": "2021-05-15" # 使用支持用户权限操作的API版本 } response = requests.get(url, headers=headers) print(f"状态码: {response.status_code}") print(f"响应内容: {response.text}")
关键验证点
- 资源路径匹配:确保
resource_path和请求URL中的路径完全对应,比如URL是dbs/MyDatabaseID/users/VinnyG/permissions,则resource_path必须是dbs/MyDatabaseID/users/VinnyG。 - payload格式严谨性:HTTP方法、资源类型必须小写,日期格式严格匹配,末尾空行不能省略。
- API版本兼容性:
x-ms-version需使用2021-05-15及以上版本,保证支持用户权限相关操作。 - 编码一致性:所有字符串统一使用UTF-8编码,避免乱码导致签名不匹配。
内容的提问来源于stack exchange,提问作者Vinny
相关产品推荐
相关产品推荐

