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

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的完整请求路径。

修改脚本中的以下部分即可解决:

  1. 修正ResourceLink的取值:
# 原错误代码
# $itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs"
# 修正后
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId
  1. 请求URI保持不变,仍需指向docs路径:
$requestUri = "$endpoint$itemResourceLink/docs"

修正后,签名生成逻辑会使用正确的资源路径进行计算,即可通过权限验证。

另外,若仅需获取集合总条目数,更高效的方式是直接调用Query Documents API执行SELECT VALUE COUNT(1) FROM c查询,无需遍历所有文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:24:52