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

使用power shell中的查询访问Azure Cosmos DB以获取特定文档时出现未经授权的访问

墨高杰
2023-03-14

参考下面的链接,我试图通过在正文中提供查询选项来修改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 net-v3/blob/master/Microsoft。azure . cosmos . samples/Usage/powershell restapi/powershell scripts/read item . PS1

我修改了如下代码:

 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
 }

 Function Get-Document {
[string] $endpoint = "https://testcosmos.documents.azure.com/"
[string] $MasterKey = "masterkey=="
[string] $databaseId = "testdb"
[string] $containerId = "containercollection1"

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

$verbMethod = "POST"
$requestUri = "$endpoint$itemResourceLink"
$authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceId $itemResourceId -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion
$itemResourceId
$itemResourceLink
$requestUri
$header = @{

    "x-ms-documentdb-isquery" = "True";

    "authorization"           = "$authKey";

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

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

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

  $queryJson = @"
 { 
"query": "SELECT * FROM TestCollection c WHERE c.userid = 2",     
"parameters": [ ] 
  }
  "@ 
   try {
      $result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method 
  $verbMethod -ContentType "application/query+json" -Body $queryJson - 
   ErrorAction Stop
    Write-Host "Read item response = "$result

}
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
    Write-Host $_.Exception|format-list -force
  }
 }

  Get-Document

错误:

响应状态码不表示成功:400(错误请求)

共有1个答案

颛孙庆
2023-03-14

我认为问题在于您的$itemResourceId变量。

请将其更改为:

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

并且您不应该收到此401错误。

如果您注意到,我从中删除了/docs

此外,我发现了这个有用的链接,您可能会发现它很有帮助:https://github.com/Azure/azure-cosmos-dotnet-v2/blob/master/samples/rest-from-.net/Program.cs.这将准确地告诉您应该使用哪些值来计算常用操作的授权标头。

更新

请将以下内容添加到您的请求标头中:

"x-ms-documentdb-query-enablecrosspartition" = "True";

以下是对我有用的完整代码:

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 = "DatabaseId"
$containerId = "ContainerId"

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

$requestUri = "$endpoint$itemResourceLink"

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

$queryJson = "{`"query`": `"SELECT * FROM test c WHERE c.id = 1 `", `"parameters`": []}"

$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-query-enablecrosspartition" = "True";
    }

try {
    $result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -Body $queryJson -ContentType "application/query+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
}
 类似资料:
  • 只要我的antMatcher上有.permitall(),这就可以很好地工作,但是当我试图保护它以便只有管理员才能进行该调用时(DB中的管理员角色是ROLE_ADMIN),它会返回401未经授权的访问,并且没有消息。我试过了 .hasRole(“admin”) .hasRole(“role_admin”) .hasAuthority(“admin”) .hasAuthority(“role_adm

  • 我想在Visual Studio 2008中将one drive for business集成到我的windows窗体应用程序中。我已经按照链接“https://dev . one drive . com/auth/aad _ oauth . htm”进行了Azure注册和Office 365认证。我可以获得登录用户的“https://{ tenant }-my . SharePoint . co

  • 我正在尝试访问azure cosmos db帐户集合文档以及集合中的每个文档。我在下面的链接中提到并更改了所有必要的cosmos db值,例如数据库、容器、itemid主密钥等, 链接: https://github . com/Azure/Azure-cosmos-dot net-v3/blob/master/Microsoft。azure . cosmos . samples/Usage/po

  • 我遇到了使用文档签名 API 的第一个障碍,需要一些帮助。 我将docusignrestapi集合导入到Postman中。我设置了iKey、iSec、encodedKeys和codeFromUrl变量。 当尝试发送'01-授权代码授予访问令牌'post API时,我每次都得到以下响应。 我尝试从Postman中删除所有内容,包括环境,并从DocuSign中删除该应用程序,然后重新开始,以便我的所有

  • 我在eclipse java中从servicenow获取访问令牌时遇到了一个未经授权的问题,但它在postman中运行良好,java代码在另一个servicenow凭据中也运行良好

  • 我有一个用于Express/Mongo健康跟踪应用程序的后端API。 每个用户都有一个数组,子文档包含一个值、一个单位和记录的日期。如果未指定单元,则默认为。 每个用户还有一个defaultUnit字段,可以为该用户指定默认单位。如果该用户在未指定单位的情况下发布称重输入,则称重输入应使用用户的默认单位(如果存在),否则默认为。 该逻辑的正确位置在哪里? 我可以在我的WeighInsControl