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

如何在PowerShell中使用AAD认证调用Azure CosmosDB REST API

问题:AAD认证调用Cosmos DB REST API返回401未授权

已配置Cosmos DB仅允许AAD认证,且为用户组分配了角色,但调用REST API查询集合时返回401错误,脚本及错误信息如下:

原脚本

Param(    
    [string] $AccountName,
    [string] $DatabaseName,
    [string] $ResourceGroupName
)

$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId)

$dateTime = [DateTime]::UtcNow.ToString("r")

$keyType="aad"
$tokenVersion="1.0"

$authHeader=[System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$($token.AccessToken)")
$header = @{authorization=$authHeader;"x-ms-version"="2018-12-31";"x-ms-documentdb-isquery"="True";"x-ms-date"=$dateTime}
$contentType= "application/query+json"
$collectionName="CapabilityManagement.Capability"
$restUri="https://$AccountName.documents.azure.com/dbs/$DatabaseName/colls/$collectionName/docs"

$query=@"
{  
  "query": "SELECT * FROM contacts c WHERE c.id = @id",  
  "parameters": [  
    {  
      "name": "@id",  
      "value": "57128516-26ff-475d-95bc-6d54c4b91b89"  
    }
  ]  
} 
"@

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$result = Invoke-RestMethod -Method Post -ContentType $contentType -Uri $restUri -Headers $header -Body $query

错误信息

Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
At C:\Users\Ksp\Documents\test.ps1:49 char:15
+ ...   $result = Invoke-RestMethod -Method Post -ContentType $contentType  ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

解决方案

1. 修正AAD令牌的获取逻辑

当前获取的令牌受众是Azure资源管理器(ARM),而Cosmos DB要求令牌受众必须是https://documents.azure.com/。修改令牌获取代码:

# 替换原令牌获取行,指定资源为Cosmos DB的受众
$token = $profileClient.AcquireAccessToken("https://documents.azure.com/")

2. 移除认证头的URL编码

认证头不需要整体URL编码,直接拼接字符串即可:

# 去掉UrlEncode,直接拼接认证头
$authHeader="type=$keyType&ver=$tokenVersion&sig=$($token.AccessToken)"

3. 验证角色分配的有效性

  • 确保角色分配的范围是Cosmos DB账户、目标数据库或集合,而非资源组。
  • 确认分配的角色包含所需权限:比如查询操作需要Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/read权限,可使用内置角色Cosmos DB Built-in Data Reader。

4. 更新API版本(可选)

建议使用较新的API版本,避免旧版本的兼容性问题:

# 修改x-ms-version为较新版本
$header = @{authorization=$authHeader;"x-ms-version"="2021-05-15";"x-ms-documentdb-isquery"="True";"x-ms-date"=$dateTime}

修改后的完整脚本

Param(    
    [string] $AccountName,
    [string] $DatabaseName,
    [string] $ResourceGroupName
)

$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
# 获取Cosmos DB专用的AAD令牌
$token = $profileClient.AcquireAccessToken("https://documents.azure.com/")

$dateTime = [DateTime]::UtcNow.ToString("r")

$keyType="aad"
$tokenVersion="1.0"

# 无需URL编码,直接拼接认证头
$authHeader="type=$keyType&ver=$tokenVersion&sig=$($token.AccessToken)"
# 使用较新的API版本
$header = @{authorization=$authHeader;"x-ms-version"="2021-05-15";"x-ms-documentdb-isquery"="True";"x-ms-date"=$dateTime}
$contentType= "application/query+json"
$collectionName="CapabilityManagement.Capability"
$restUri="https://$AccountName.documents.azure.com/dbs/$DatabaseName/colls/$collectionName/docs"

$query=@"
{  
  "query": "SELECT * FROM contacts c WHERE c.id = @id",  
  "parameters": [  
    {  
      "name": "@id",  
      "value": "57128516-26ff-475d-95bc-6d54c4b91b89"  
    }
  ]  
} 
"@

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$result = Invoke-RestMethod -Method Post -ContentType $contentType -Uri $restUri -Headers $header -Body $query

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:25:20