访问 Cosmos Db 时处于未授权状态 Collection 掌权文档 shell

Unauthorized status while accessing Cosmos Db Collection Documents in power shell

我正在尝试访问 azure cosmos db 帐户 collection 文档以及 collection 中的每个文档。我在下面提到 link 并更改了所有必要的 cosmos db 值,如 databaseid、container、itemid master key 等,

Link:

https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi/PowerShellScripts/ReadItem.ps1

但是我在 Powershell 中 运行 时出现以下错误。

错误:

  StatusCode: 401
  Exception Message: The remote server returned an error: (401) Unauthorized.
  System.Net.WebException: The remote server returned an error: (401) Unauthorized.
   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
  at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()

注意:当我在邮递员中尝试相同时,我正在获取文档列表但是当我试图获取特定文档时。我遇到错误。

错误:

  The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign:

仅供参考:我是 Azure 门户中 Cosmodb 帐户的贡献者角色

参数:

   $endpoint = "https://testcosmos.documents.azure.com:443/"
  $MasterKey = "<Key from Cosmos db account>"
  $KeyType = "master"
 $TokenVersion = "1.0"
 $date = Get-Date
 $utcDate = $date.ToUniversalTime()
 $xDate = $utcDate.ToString('r', 
  [System.Globalization.CultureInfo]::InvariantCulture)
 $databaseId = "testdb"
  $containerId = "containercollection"
 $itemResourceType = "docs"
$ItemId="1"
 $itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
  $itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
  $verbMethod = "GET"

  $header = @{

    "authorization"         = "$authKey";

    "x-ms-version"          = "2018-12-31";

   "Cache-Control"         = "no-cache";

    "x-ms-date"             = "$xDate"

    "Accept"                = "application/json";

    "User-Agent"            = "PowerShell-RestApi-Samples";

    "x-ms-documentdb-partitionkey" = '["testPK"]'
}

我曾尝试评论 "Accept"、"User-Agent"、Cache-Control header 选项,但没有成功。 我也尝试只获取没有 itemID 的 /docs 列表,但这也是徒劳的。

$result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -ContentType "application/json"
Write-Host "Read item response = "$result

更新代码: 我终于明白为什么会出现问题了。它既不是身份验证问题也不是资源 ID。我在 headers 中传递分区键,它不是按照 sample 硬编码的。当我将值传递给分区键时,它没有正确获取,因此导致问题。下面是我的动态代码传递分区键

"x-ms-documentdb-partitionkey" = '["$Partitionkey"]' -- Displaying as 
[$Partitionkey] but it must print in headers like ["partitionkeyValue"]

正在尝试解决这个问题。非常感谢您的建议。

我尝试了以下代码,它对我来说效果很好。我能够获取文档详细信息:

Add-Type -AssemblyName System.Web

Function Generate-MasterKeyAuthorizationSignature{

    [CmdletBinding()]

    param (

        [string] $Verb,
        [string] $ResourceId,
        [string] $ResourceType,
        [string] $Date,
        [string] $MasterKey,
        [String] $KeyType,
        [String] $TokenVersion
    )

    $keyBytes = [System.Convert]::FromBase64String($MasterKey)

    $sigCleartext = @($Verb.ToLower() + "`n" + $ResourceType.ToLower() + "`n" + $ResourceId + "`n" + $Date.ToString().ToLower() + "`n" + "" + "`n")
    Write-Host "sigCleartext = " $sigCleartext

    $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
}

$endpoint = "https://account-name.documents.azure.com:443/"
$MasterKey = "account-key"

$KeyType = "master"
$TokenVersion = "1.0"
$date = Get-Date
$utcDate = $date.ToUniversalTime()
$xDate = $utcDate.ToString('r', [System.Globalization.CultureInfo]::InvariantCulture)
$databaseId = "MyDatabaseId"
$containerId = "MyContainerId"
$itemId = "TestItem"
$itemResourceType = "docs"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$verbMethod = "GET"

$requestUri = "$endpoint$itemResourceLink"

$authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceId $itemResourceId -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion

$header = @{

        "authorization"         = "$authKey";

        "x-ms-version"          = "2018-12-31";

        "Cache-Control"         = "no-cache";

        "x-ms-date"             = "$xDate";

        "Accept"                = "application/json";

        "User-Agent"            = "PowerShell-RestApi-Samples";

        "x-ms-documentdb-partitionkey" = '["testPk"]'
    }

try {
    $result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -ContentType "application/json"
    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
}

更新

关于您对动态指定分区键值的评论,请尝试以下操作:

"x-ms-documentdb-partitionkey" = '["' + $Partitionkey + '"]'

首先,我可以使用与@Gaurav Mantri 相同的 github 代码成功查询我的项目。您的错误代码是 401 授权问题,因此我假设您在生成 MasterKeyAuthorizationSignature 时犯了一些错误,尤其是 $itemResourceId 的值。请参考 REST API document.

2 部分:

1.Query 一个特定的项目:

$itemId = "1"
$itemResourceType = "docs"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId

2.List 个特定集合中的项目:

没有#itemId

$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"