使用Powershell调用Rest API-CosmosDb [英] Invoking Rest API using Powershell - CosmosDb

查看:100
本文介绍了使用Powershell调用Rest API-CosmosDb的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Cosmos DB REST Api部署cosmos数据库.我正在使用一个函数来构建授权标头,并且从 https://gallery.technet.microsoft.com/scriptcenter/How-to-query-Azure-Cosmos-0a9aa517 链接.对于GET&来说,它工作得很好. POST,但是当我尝试执行PUT命令时,我总是遇到错误.

I was trying to deploy cosmos database using Cosmos DB REST Api. I'm using a function to build the authorisation header and I got the script from https://gallery.technet.microsoft.com/scriptcenter/How-to-query-Azure-Cosmos-0a9aa517 link. It works perfectly fine for GET & POST however when I tried to execute a PUT command I'm always getting below error.

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

Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.

我正在尝试更新Cosmos集合的报价,但总是以错误结尾,我不知道是什么原因.我还检查了标头和Microsoft文档的授权,对我来说还不错.请参考 https://docs.microsoft.com/en -us/rest/api/documentdb/replace-an-offer (用于Uri)和标头.我的要求和回应如下

Im trying to update the offer for Cosmos collection but it always ends with the error and I couldn't understand whats the reason. I also checked my headers and authorisation with Microsoft documentation and looks fine to me. Refer https://docs.microsoft.com/en-us/rest/api/documentdb/replace-an-offer for Uri and headers required. My request and response are below

请求

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请求因授权错误而失败,我丢失了什么以及如何纠正它.

Can someone throw me some help as why my PUT requests are failed with authorisation error, what I'm missing and how can I correct it.

推荐答案

响应消息明确指出了用于验证的有效负载.在Generate-MasterKeyAuthorizationSignature中跟踪'$ payLoad'将很快解决该问题.

Response message clearly states used payload for verification. Tracing '$payLoad' in Generate-MasterKeyAuthorizationSignature will quickly revel the issue.

您需要至少解决以下两个问题,

You need to address at-least below two issues for this to work

  • RepalceOffer文档说明了商品的RID,而您是 传递集合名称.
  • ResourceLin硬编码:$ ResourceLink =要约"中的要约",它需要指向资源的RID.
  • RepalceOffer documentation states RID of the offer, instead you are passing the collection name.
  • ResourceLin hardcoded: $ResourceLink = "offers" in Modify-Offer where as it needs to point to the RID of the resource.

这里是经过稍微修改的代码,应该可以正常工作

Here is slightly modified code which should do job

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.这是一个示例代码,用于更新帐户的首次报价.

Other alternative recommended approach if possible is to consume client SDK in Powershell. Here is a sample code which updates first offer of the account.

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调用Rest API-CosmosDb的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆