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

使用Powershell调用Rest API-CosmosDb

拓拔坚
2023-03-14

我试图使用cosmos DB REST Api部署Cosmos数据库。我使用一个函数来构建授权头,我从https://gallery . TechNet . Microsoft . com/script center/How-to-query-Azure-Cosmos-0a9aa 517链接获得了脚本。对于GET来说,它工作得非常好

Invoke-RestMethod:远程服务器返回错误:(401) 未经授权。

我试图更新Cosmos系列的报价,但总是以错误结束,我不知道原因是什么。我还用Microsoft文档检查了我的标题和授权,我觉得很好。请参阅https://docs.microsoft.com/en-us/rest/api/documentdb/replace-an-offer需要Uri和标头。我的请求和答复如下:

要求

PUT https: //mycosmosdb.documents.azure.com:443/offers/mycollection HTTP/1.1
authorization: type % 3dmaster % 26ver % 3d1.0 % 26sig % 3dIgWkszNS % 2b94fUEyrG8frByB2PWSc1ZEszc06GUeuW7s % 3d
x - ms - version: 2017 - 02 - 22
x - ms - date: Wed, 02 Aug 2017 08: 40: 37 GMT
User - Agent: Mozilla / 5.0(Windows NT; Windows NT 10.0; en - US)WindowsPowerShell / 5.1.15063.483
Content - Type: application / json
Host: mycosmosdb.documents.azure.com
Content - Length: 269
{
    "offerVersion": "V2",
    "offerType": "Invalid",
    "content": {
        "offerThroughput": 500,
        "offerIsRUPerMinuteThroughputEnabled": false
    },
    "resource": "dbs/xterf==/colls/STuexopre=/",
    "offerResourceId": "STuexopre=",
    "id": "xiZw",
    "_rid": "xiZw"
}

回应

HTTP / 1.1 401 Unauthorized
Transfer - Encoding: chunked
Content - Type: application / json
Content - Location: https: //mycosmosdb.documents.azure.com/offers/variantstockquantity
Server: Microsoft - HTTPAPI / 2.0
x - ms - activity - id: 6f7be3c8 - cfa2 - 4d5e - ad69 - fb14ef218980
Strict - Transport - Security: max - age = 31536000
    x - ms - gatewayversion: version = 1.14.57.1
    Date: Wed, 02 Aug 2017 08: 40: 35 GMT

163{
    "code": "Unauthorized",
    "message": "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: 'put\noffers\mycollection\nwed, 02 aug 2017 08:40:37 gmt\n\n'\r\nActivityId: 6f7be3c8-cfa2-4d5e-ad69-fb14ef218980"
}
0

我的Powershell代码

Function Generate-MasterKeyAuthorizationSignature
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$verb,
        [Parameter(Mandatory=$true)][String]$resourceLink,
        [Parameter(Mandatory=$true)][String]$resourceType,
        [Parameter(Mandatory=$true)][String]$dateTime,
        [Parameter(Mandatory=$true)][String]$key,
        [Parameter(Mandatory=$true)][String]$keyType,
        [Parameter(Mandatory=$true)][String]$tokenVersion
    )

    $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
    $hmacSha256.Key = [System.Convert]::FromBase64String($key)

    If ($resourceLink -eq $resourceType) {
        $resourceLink = ""
    }

    $payload = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n$resourceLink`n$($dateTime.ToLowerInvariant())`n`n"
    $hashPayload = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payload))
    $signature = [System.Convert]::ToBase64String($hashPayload);

    [System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$signature")
}


Function Modify-Offer
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$DocumentDBApi,
        [Parameter(Mandatory=$true)][String]$EndPoint,
        [Parameter(Mandatory=$true)][String]$MasterKey,
        [Parameter(Mandatory=$true)][String]$CollectionName
    )
    

    $Verb = "PUT"
    $ResourceType = "offers";
    $ResourceLink = "offers"

    $body = '{
    "offerVersion": "V2",
    "offerType": "Invalid",
    "content": {
        "offerThroughput": 500,
        "offerIsRUPerMinuteThroughputEnabled": false
    },
    "resource": "dbs/xterf==/colls/STuexopre=/",
    "offerResourceId": "STuexopre=",
    "id": "xiZw",
    "_rid": "xiZw"
}'
    $dateTime = [DateTime]::UtcNow.ToString("r")
    $authHeader = Generate-MasterKeyAuthorizationSignature -verb $Verb -resourceLink $ResourceLink -resourceType $ResourceType -key $MasterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
    $header = @{authorization=$authHeader;"x-ms-version"=$DocumentDBApi;"x-ms-date"=$dateTime}
    $contentType= "application/json"
    $queryUri = "$EndPoint$ResourceLink/$CollectionName"
    $result = Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $queryUri -Headers $header -Body $body
    $result | ConvertTo-Json -Depth 10

}


Modify-Offer -EndPoint $CosmosDBEndPoint -MasterKey $MasterKey -DocumentDBApi $DocumentDBApiVersion -CollectionName $ColName

有人能给我一些帮助吗?为什么我的PUT请求失败,并出现授权错误,我错过了什么,我该如何纠正它。

共有1个答案

宰父俊民
2023-03-14

响应消息清楚地说明了用于验证的有效载荷。在Generate-MasterKeyAuthorizationSignature中跟踪' $payLoad '将很快揭示该问题。

您至少需要解决以下两个问题才能使其发挥作用

  • RepalceOffer留档状态为offer的RID,而不是传递集合名称。
  • ResourceLin硬编码:$ResourceLink=Modify-Offer中的“提供”,因为它需要指向资源的RID。

这是应该做工作的稍微修改的代码

Function Generate-MasterKeyAuthorizationSignature
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$verb,
        [Parameter(Mandatory=$true)][String]$resourceLink,
        [Parameter(Mandatory=$true)][String]$resourceType,
        [Parameter(Mandatory=$true)][String]$dateTime,
        [Parameter(Mandatory=$true)][String]$key,
        [Parameter(Mandatory=$true)][String]$keyType,
        [Parameter(Mandatory=$true)][String]$tokenVersion
    )

    $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
    $hmacSha256.Key = [System.Convert]::FromBase64String($key)

    If ($resourceLink -eq $resourceType) {
        $resourceLink = ""
    }

    $payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n$resourceLink`n$($dateTime.ToLowerInvariant())`n`n"
    $hashPayLoad = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payLoad))
    $signature = [System.Convert]::ToBase64String($hashPayLoad);
    Write-Host $payLoad

    [System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$signature")
}


Function Modify-Offer
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$DocumentDBApi,
        [Parameter(Mandatory=$true)][String]$EndPoint,
        [Parameter(Mandatory=$true)][String]$MasterKey,
        [Parameter(Mandatory=$true)][String]$OfferRID
    )


    $Verb = "PUT"
    $ResourceType = "offers";

    $body = '{
    "offerVersion": "V2",
    "offerType": "Invalid",
    "content": {
        "offerThroughput": 600,
        "offerIsRUPerMinuteThroughputEnabled": false
    },
"resource": "dbs/xterf==/colls/STuexopre=/",
"offerResourceId": "STuexopre=",
"id": "xiZw",
"_rid": "xiZw"
}'
    $dateTime = [DateTime]::UtcNow.ToString("r")
    $authHeader = Generate-MasterKeyAuthorizationSignature -verb $Verb -resourceLink $OfferRID -resourceType $ResourceType -key $MasterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
    $header = @{authorization=$authHeader;"x-ms-version"=$DocumentDBApi;"x-ms-date"=$dateTime}
    $contentType= "application/json"
    $queryUri = "$EndPoint$ResourceType/$OfferRID"
    $result = Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $queryUri -Headers $header -Body $body
    $result | ConvertTo-Json -Depth 10

}

Modify-Offer -EndPoint $CosmosDBEndPoint -MasterKey $MasterKey -DocumentDBApi $DocumentDBApiVersion -OfferRID $ColName

如果可能的话,建议的其他替代方法是在Powershell中使用客户端SDK。下面是一个示例代码,用于更新帐户的第一个产品/服务。

Add-Type -Path "...\Microsoft.Azure.Documents.Client.dll"
$client=New-Object Microsoft.Azure.Documents.Client.DocumentClient($CosmosDBEndPoint, $MasterKey)
$offersEnum=$client.ReadOffersFeedAsync().Result.GetEnumerator();
if ($offersEnum.MoveNext())
{
    $targetOffer=$offersEnum.Current
    $offerUpdated=New-Object Microsoft.Azure.Documents.OfferV2($targetOffer, 600, $FALSE)
    $client.ReplaceOfferAsync($offerUpdated).Result
}
 类似资料:
  • 本文向大家介绍Powershell小技巧之使用WS-Man来调用PowerShell命令,包括了Powershell小技巧之使用WS-Man来调用PowerShell命令的使用技巧和注意事项,需要的朋友参考一下 虽然PowerShell远程管理被构建在 WS-Management的之上,但它是协议中的协议。如果尝试使用 PSRP (PowerShell远程处理协议)直接进行交互,本质上需要在客户端

  • 我使用已签名的URL从使用Air的移动设备上传blob。 我有两个问题: 使用签名 URL 上传 Blob 时,我假设我不需要按照文档中所述包含所有标头。我是否认为我只需要对URL执行请求,并将编码到正文中的文件包含在正文中,设置为? http://msdn . Microsoft . com/en-us/library/windows azure/DD 179451 . aspx (Upload

  • 问题内容: 我正在尝试从python这样启动PowerShell脚本: 问题是我得到以下错误: 无法加载文件C:\ Users \ sztomi \ workspace \ myproject \ buildxml.ps1,因为在此系统上禁用了脚本的执行。请参阅“获取有关about_signing的帮助”以了解更多详细信息。 尽管事实上我很早以前确实通过键入管理员运行的PS终端来启用Powersh

  • 我已经创建了自定义PowerShell cmdlet,并且正在为它们编写测试脚本。 我得到cmdlet的列表,并且我必须向它传递一个非字符串类型的对象。我尝试使用Invoke-Expression,但我得到一个错误,它使用字符串名称作为参数值。

  • 当您调用时,下面的Powershell错误意味着什么? System.Management.Automation.ValidationMetadataException:参数“+”不属于ValidateSet属性指定的集“Unicode,utf7,utf8,utf32,ascii,bigendianunicode,default,OEM”。提供一个集合中的参数,然后重试该命令。在System.Ma

  • 我有一个管理Web应用程序位于远程服务器上。这个应用程序是使用MEAN堆栈编写的,我有一个连接到网络应用程序所需的所有RESTful路由的列表。 我正在编写一个Java客户端应用程序,它需要从这个管理应用程序发送和接收数据。如果我有服务器的IP地址和REST路由,如何将客户端连接到web应用程序? 我想我需要提供一个到服务器和RESTAPI文件的URL连接,然后只需调用路由函数,如和。