Powershell 访问power shell中的Cosmos Db收集文档时处于未经授权状态

Powershell 访问power shell中的Cosmos Db收集文档时处于未经授权状态,powershell,azure-cosmosdb,azure-powershell,azure-cosmosdb-sqlapi,Powershell,Azure Cosmosdb,Azure Powershell,Azure Cosmosdb Sqlapi,我正在尝试访问azure cosmos db帐户集合文档以及集合中的每个文档。我参考了下面的链接,并更改了所有必要的cosmos db值,如databaseid、container、itemid主密钥等 链接: 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

我正在尝试访问azure cosmos db帐户集合文档以及集合中的每个文档。我参考了下面的链接,并更改了所有必要的cosmos db值,如databaseid、container、itemid主密钥等

链接:

  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:
   $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"]'
}

但在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:
   $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"]'
}
仅供参考:我是azure门户中Cosmodb帐户的贡献者角色

参数:

  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:
   $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"]'
}
更新代码:我终于能够理解为什么会出现这个问题。它既没有身份验证问题,也没有资源ID。我在头文件中传递分区键,它不是按照示例硬编码的。当我将值传递给分区键时,它并没有正确地接受,因此导致了问题。下面是我传递分区键的动态代码

"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 + '"]'

我尝试了下面的代码,它对我很有效。我能够获取文档详细信息:

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
auth issue,因此我假设您在生成
MasterKeyAuthorizationSignature
时犯了一些错误,尤其是
$itemResourceId
的值。请参考REST API

2部分:

1.查询特定项目:

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

2.列出特定集合中的项目:

#itemId

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

首先,我可以使用与@Gaurav Mantri相同的github代码成功地查询我的物品。您的错误代码是
401
auth issue,因此我假设您在生成
MasterKeyAuthorizationSignature
时犯了一些错误,尤其是
$itemResourceId
的值。请参考REST API

2部分:

1.查询特定项目:

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

2.列出特定集合中的项目:

#itemId

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

请编辑您的问题并包括您传递给此PS函数的参数。您的
$itemrourceid
$itemrourcelink
中是否缺少
$itemrourceid
?它们都应该是“
”dbs/“++$databaseId+”/colls/“++$containerId+”/docs/“++$ItemId
”。添加$ItemId也会产生相同的错误。因此,我专门删除了,以了解我是否得到了整个文档列表,但没有得到。我只是从(您正在引用的链接)复制了代码,并运行了代码,我能够获取文档的详细信息。我刚刚根据我的帐户设置更改了端点、主密钥、数据库和容器id。团队,我已更新了代码。请编辑您的问题并包括您传递给此PS函数的参数。您的
$itemResourceId
$itemResourceLink
中是否缺少
$itemResourceId
?它们都应该是“
”dbs/“++$databaseId+”/colls/“++$containerId+”/docs/“++$ItemId
”。添加$ItemId也会产生相同的错误。因此,我专门删除了,以了解我是否得到了整个文档列表,但没有得到。我只是从(您正在引用的链接)复制了代码,并运行了代码,我能够获取文档的详细信息。我只是根据我的帐户设置更改了端点、主密钥、数据库和容器id。团队,我已经更新了我的代码。嗨,当我尝试上述测试时,我有一个问题。如果我在分区集合中有一个没有分区键字段的项(假设pk是
name
)。因为此项没有
名称
列。那么如何设置
“x-ms-documentdb-partitionkey”
,我可以在java sdk中设置
Undefined.Value()
,它工作得很好。但是这里没有PS。我试过
{}
。如果你有什么想法,请你带我去好吗?提前谢谢你。@JayGong Gret问题!我尝试了
{}
,它对我很有效。这就是我使用的:
“x-ms-documentdb-partitionkey”='[{}]'
。如果每次调用API时都必须传递一些动态值,该怎么办。假设我有分区键,我希望每次传递一个不同的值,而不是硬编码的值。我尝试了下面的“x-ms-documentdb-partitionkey”=“[+$partitionkey+”]”-将[TESTPK]打印为[“TESTPK”]尝试
“x-ms-documentdb-partitionkey”='['+$partitionkey+']'.
。应该能用的。谢谢。嗨,当我试过上面的测试时,我有一个问题。如果我在分区集合中有一个没有分区键字段的项(假设pk是
name
)。因为此项没有
名称
列。那么如何设置
“x-ms-documentdb-partitionkey”
,我可以在java sdk中设置
Undefined.Value()
,它工作得很好。但是这里没有PS。我试过
{}
。如果你有什么想法,请你带我去好吗?提前谢谢你。@JayGong Gret问题!我尝试了
{}
,它对我很有效。这就是我使用的:
“x-ms-documentdb-partitionkey”='[{}]'
。如果每次调用API时都必须传递一些动态值,该怎么办。假设我有分区键,我希望每次传递一个不同的值,而不是硬编码的值。我尝试了下面的“x-ms-documentdb-partitionkey”=“[+$partitionkey+”]”-将[TESTPK]打印为[“TESTPK”]尝试
“x-ms-documentdb-partitionkey”='['+$partitionkey+']'.
。应该有用的,谢谢。