Azure Cosmos DB List Documents API调用出现401未授权问题(PowerShell)
问题描述
使用PowerShell调用Azure Cosmos DB的List (ReadFeed) Documents API请求集合时,收到401 Unauthorized响应。
注意:同一脚本仅做少量修改后,调用Query Documents API检索特定项可正常运行,因此排除权限或令牌/授权问题。已参考C#令牌构造文档,但未发现问题。
脚本
以下是使用的PowerShell脚本:
Import-Module Az.Accounts -MinimumVersion 3.0.0 Import-Module Az.Resources Import-Module Az.CosmosDB Add-Type -AssemblyName System.Web Function Generate-MasterKeyAuthorizationSignature{ [CmdletBinding()] param ( [string] $Verb, [string] $ResourceLink, [string] $ResourceType, [string] $Date, [string] $MasterKey, [String] $KeyType, [String] $TokenVersion ) $keyBytes = [System.Convert]::FromBase64String($MasterKey) $sigCleartext = @($Verb.ToLower() + "`n" + $ResourceType.ToLower() + "`n" + $ResourceLink + "`n" + $Date.ToString().ToLower() + "`n" + "" + "`n") $bytesSigClear = [Text.Encoding]::UTF8.GetBytes($sigCleartext) $hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (, $keyBytes) $hash = $hmacsha.ComputeHash($bytesSigClear) $signature = [System.Convert]::ToBase64String($hash) $key = [System.Web.HttpUtility]::UrlEncode('type='+$KeyType+'&ver='+$TokenVersion+'&sig=' + $signature) return $key } #$AccountName = "cosmosAccount" #$ResourceGroupName = "cosmosRG" #$databaseId = "cosmosDB" #$containerId = "cosmosContainer" $KeyType = "master" $TokenVersion = "1.0" $itemResourceType = "docs" $itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs" $verbMethod = "get" $endpoint = "https://$AccountName.documents.azure.com:443/" $date = Get-Date $utcDate = $date.ToUniversalTime() $xDate = $utcDate.ToString('r', [System.Globalization.CultureInfo]::InvariantCulture) $requestUri = "$endpoint$itemResourceLink" $MasterKey = $(Get-AzCosmosDBAccountKey -ResourceGroupName $ResourceGroupName -Name $AccountName).PrimaryMasterKey $authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceLink $itemResourceLink -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion $header = @{ "authorization" = "$authKey"; "x-ms-version" = "2018-12-31"; "x-ms-date" = "$xDate"; } try { $result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod Write-Host "Read item response = "$result return "ReadItemSuccess"; } catch { # Dig into the exception to get the Response details. # Note that value__ is not a typo. Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ Write-Host "Exception Message:" $_.Exception.Message echo $_.Exception|format-list -force }
目标
希望实现一个PowerShell脚本,获取指定Azure Cosmos DB集合中的总条目数。计划通过List Documents(来自ChangeFeed)操作,利用响应中的_count属性来获取该数值。
解决方案
出现401 Unauthorized的核心原因是签名构造时使用了错误的ResourceLink。对于List (ReadFeed) Documents API,签名所需的ResourceLink应指向容器级别(dbs/{db-id}/colls/{coll-id}),而非包含/docs的完整请求路径。
修改脚本中的以下部分即可解决:
- 修正ResourceLink的取值:
# 原错误代码 # $itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs" # 修正后 $itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId
- 请求URI保持不变,仍需指向docs路径:
$requestUri = "$endpoint$itemResourceLink/docs"
修正后,签名生成逻辑会使用正确的资源路径进行计算,即可通过权限验证。
另外,若仅需获取集合总条目数,更高效的方式是直接调用Query Documents API执行SELECT VALUE COUNT(1) FROM c查询,无需遍历所有文档。
内容的提问来源于stack exchange,提问作者Yousef Imran
相关产品推荐
相关产品推荐

