当前位置: 首页 > 知识库问答 >
问题:

在电源外壳中访问 Cosmos 数据库集合文档时出现未经授权的状态

姬歌者
2023-03-14

我正在尝试访问azure cosmos db帐户集合文档以及集合中的每个文档。我在下面的链接中提到并更改了所有必要的cosmos db值,例如数据库、容器、itemid主密钥等,

链接:

https://github . com/Azure/Azure-cosmos-dot net-v3/blob/master/Microsoft。azure . cosmos . samples/Usage/powershell restapi/powershell scripts/read item . PS1

但是我在动力外壳中运行时收到以下错误。

错误:

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

我已经尝试评论“接受”,“用户代理”,缓存控制头选项,但徒劳无功。我还试图只获取没有itemID的/docs列表,但也是徒劳的。

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

更新代码:我终于能够理解为什么问题来了。这既不是身份验证问题,也不是resourceID问题。我在头中传递分区键,它不是按照样本硬编码的。当我将值传递给分区键时,它没有正确地接受,因此导致了问题。下面是我的动态代码传递分区键

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

我正在努力解决这个问题。非常感谢你的建议。

共有2个答案

阎懿轩
2023-03-14

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

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 + '"]'
邵子平
2023-03-14

首先,我可以用github代码成功地查询我的项目,就像@Gaurav Mantri一样。您的错误代码是< code>401 auth issue,所以我假设您在生成< code > MasterKeyAuthorizationSignature 时犯了一些错误,尤其是< code>$itemResourceId的值。请参考REST API文档。

2部分:

1.查询特定项目:

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

2.列出特定收藏中的项目:

没有< code>#itemId

$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
 类似资料:
  • 参考下面的链接,我试图通过在正文中提供查询选项来修改Github示例以获得特定的文档。 链接:https://docs.microsoft.com/en-us/rest/api/cosmos-db/querying-cosmosdb-resources-using-the-rest-api Github示例:https://github . com/Azure/Azure-cosmos-dot n

  • 问题内容: 我仅在使用PHP api实际版本的示例并使用examples文件夹的“ service-account.php”文件时遇到问题。 原来是用于显示“ Books API”的,并且通过我的个人凭据配置可以很好地工作,但是在我的xcase中,我需要通过directory.groups.get服务进行访问,以获取Google网上论坛邮件列表的会员帐户列表,所以我在其中更改了原始代码: 无论我做

  • 只要我的antMatcher上有.permitall(),这就可以很好地工作,但是当我试图保护它以便只有管理员才能进行该调用时(DB中的管理员角色是ROLE_ADMIN),它会返回401未经授权的访问,并且没有消息。我试过了 .hasRole(“admin”) .hasRole(“role_admin”) .hasAuthority(“admin”) .hasAuthority(“role_adm

  • 我正在建立一个应用程序,两个不同的用户将编辑相同的文件在线,只使用纯文本。为此,我使用GitHub上的google-api-php-client-master。 有一些例子,但我不明白我需要做什么才能达到目的。官方文档是不推荐的,因为它是一个不在线的库,所有的类都有不同的名称和工作方式。 我已经获得了我的凭据,并知道如何获得托管在我的驱动器帐户上的文档列表。但现在我需要: null 我不指望任何人

  • 我正在尝试添加新主机,并将证书和密钥(即 /etc/kubernetes/pki/apiserver-kubelet-client.crt)从当前主机复制到新主机。我注意到在我执行“kubeadm init--config=config.yaml”之后,这个密钥(可能所有密钥)正在更改(kubeadm init本身是成功的)…为什么会发生这种情况,这可能是我的新主机处于NotReady状态的根本原