gpt4 book ai didi

bash - 使用 bash、Azure CLI 和 REST API 访问 CosmosDB - 如何正确获取 token 和哈希?

转载 作者:行者123 更新时间:2023-12-02 05:52:45 25 4
gpt4 key购买 nike

我的最终目标是使用 bash 和 Azure CLI 将文档上传到现有的 CosmosDB (SQL) 实例。问题是:Azure CLI 确实 not offer a command to modify documents .

为了解决这个问题,我研究了 az rest 命令,并希望调用 CosmosDB 的 REST API 来完成任务,但经过几个小时的不成功尝试后,我总是收到错误:

Unauthorized({"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: 'get\ndbs\n\nsat, 25 apr 2020 13:50:22 +0000\n\n'\r\nActivityId: ..., Microsoft.Azure.Documents.Common/2.10.0"})

为了暂时简单起见,我尝试使用 REST API as described in the docs 列出我的所有数据库。如果可行,请继续实际的文档上传。

我也在尝试按照 in the docs 提供的说明进行操作关于如何生成授权 header 。

获取数据库列表的请求使用以下格式:GET https://{databaseaccount}.documents.azure.com/dbs

这是我的 bash 脚本,其中突出显示了问题。

第 1 部分:获取访问 token - 问题:这是正确的 token 吗?

masterKey=$(az cosmosdb keys list --name MYDBINSTANCENAME --query primaryMasterKey --output tsv)

第 2 部分:生成有效负载进行哈希 - 所有内容必须小写

verb="get"
resourceType="dbs"
resourceLink="dbs"
now=$((date -uR) | tr '[A-Z]' '[a-z]')
payload="$verb\n$resourceType\n$resourceLink\n$now\n\\n"

第 3 部分:对有效负载进行哈希处理 - 问题:此哈希的结果与 what the sample code in C# builds 不同。因此,其中之一必定是错误的,但两者都会导致相同的错误消息。

hashedPayload=$(printf $payload | openssl dgst -sha256 -hmac $masterKey -binary)

第 4 部分:创建所需的身份验证字符串并转换为 Base 64 - 问题是与 az rest 一起使用所需的 Base 64 编码吗?

authString="type=master&ver=1.0&sig=$hashedPayload" | base64

第 5 部分:创建 header 字符串。这是使用 JSON 表示法,因为空白分隔方法不起作用,although the docs state it should .

headers="{\"x-ms-date\": \"$now\", \"x-ms-version\": \"2018-12-31\", \"x-ms-documentdb-isquery\": \"true\", \"Content-Type\": \"application/query+json\", \"Authorization\": \"$authString\"}"

第 6 部分:调用 REST API

az rest --verbose -m get -u "https://MYDBINSTANCENAME.documents.azure.com:443/dbs" --headers $headers

输出:

Request URL: 'https://MYDBINSTANCENAME.documents.azure.com:443/dbs'
Request method: 'GET'
Request headers:
'User-Agent': 'AZURECLI/2.4.0 (HOMEBREW)'
'Accept-Encoding': 'gzip, deflate'
'Accept': '*/*'
'Connection': 'keep-alive'
'x-ms-date': 'sat, 25 apr 2020 13:54:10 +0000'
'x-ms-version': '2018-12-31'
'x-ms-documentdb-isquery': 'true'
'Content-Type': 'application/query+json'
'Authorization': 'type%3dmaster%26ver%...'
'x-ms-client-request-id': 'a55357fe-411c-4adf-9fd6-1a255e010cca'
'CommandName': 'rest'
'ParameterSetName': '--verbose -m -u --headers'
Request body:
None
Response status: 401
Response headers:
'Transfer-Encoding': 'chunked'
'Content-Type': 'application/json'
'Content-Location': 'https://MYDBINSTANCENAME.documents.azure.com/dbs'
'Server': 'Microsoft-HTTPAPI/2.0'
'x-ms-activity-id': '9119f8bd-53d9-4a87-8aff-a887ec652fed'
'Strict-Transport-Security': 'max-age=31536000'
'x-ms-gatewayversion': 'version=2.10.0'
'Date': 'Sat, 25 Apr 2020 13:54:11 GMT'
Response content:
{"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: 'get\ndbs\n\nsat, 25 apr 2020 13:54:10 +0000\n\n'\r\nActivityId: 9119f8bd-53d9-4a87-8aff-a887ec652fed, Microsoft.Azure.Documents.Common/2.10.0"}

最佳答案

感谢您的支持@Gaurav Mantri 和@Mark Brown。您的评论帮助我们避免了一百万次被纸割伤:-)

我已经启动了一个存储库,用于收集 Azure CLI bash 脚本。找到它 https://github.com/Krumelur/AzureScripts

让我回答我自己的问题并提供一个读取 CosmosDB 实例中现有数据库的脚本。

这将在浏览器窗口中启动交互式登录。

az login

指定我们要访问的资源。 URI 以及所需的参数值可以在以下位置找到:https://learn.microsoft.com/en-us/rest/api/cosmos-db/cosmosdb-resource-uri-syntax-for-rest

comsosDbInstanceName="YOUR INSTANCE NAME GOES HERE"
baseUrl="https://$comsosDbInstanceName.documents.azure.com/"
verb="get"
resourceType="dbs"
resourceLink="dbs"
resourceId=""

获取 CosmosDB 的主 key 。我们需要这个才能访问。该 key 与门户上 CosmosDB 实例的“ key ”部分中找到的 key 相同。主键是 REST API 所说的“主”键。

masterKey=$(az cosmosdb keys list --name $comsosDbInstanceName --query primaryMasterKey --output tsv)
echo "Masterkey: $masterKey"

CosmosDB REST API 需要哈希授权 header :https://learn.microsoft.com/de-de/rest/api/cosmos-db/access-control-on-cosmosdb-resources#authorization-header

要获取 HTTP 格式的日期,区域设置必须设置为 US。否则,日期名称将被本地化(例如德语)。

bash 不直接支持 HTTP 格式。要使其正常工作,请将当前时区设置为 GMT。时间格式如下所示:“mon, 27 apr 2020 09:46:58 gmt”。

now=$(env LANG=en_US TZ=GMT date '+%a, %d %b %Y %T %Z')
echo "Date: " $now

以预期格式连接动词、资源类型、资源 ID 和日期。 REST API 要求签名为小写。

我没有意识到的“小”问题:输出字符串时尾随换行符 (\n) 总是被截断。这会破坏哈希值,因为 CosmosDB 期望它们在那里。这就是为什么在小写操作之后添加了两个尾随换行符。

signature="$(printf "%s" "$verb\n$resourceType\n$resourceId\n$now" | tr '[A-Z]' '[a-z]')\n\n"
echo "Signature: $signature"

使用 CosmosDB 实例的主键计算签名的哈希值。请参阅https://superuser.com/questions/1546027/what-is-the-openssl-equivalent-of-this-given-c-hashing-code/1546036详细了解为什么这如此棘手。 tl;博士;版本:OpenSSL 和服务器实现以不同的方式解释哈希 key 。

hexKey=$(printf "$masterKey" | base64 --decode | hexdump -v -e '/1 "%02x"')
echo "Hex key: " $hexKey
hashedSignature=$(printf "$signature" | openssl dgst -sha256 -mac hmac -macopt hexkey:$hexKey -binary | base64)
echo "Hashed signature: $hashedSignature"```

哈希签名预计会进行 URL 编码。当然,bash 中没有内置方法可以做到这一点。天啊。幸运的是,我们正在处理一个 Base64 字符串。唯一需要编码的字符是等号,它变成“%3d”。

使用格式“type={typeoftoken}&ver={tokenversion}&sig={hashsignature}”构建授权 header

authString="type=master&ver=1.0&sig=$hashedSignature"
echo "Auth string: $authString"

Auth 字符串应采用 URL 编码。当然,bash 中没有内置方法可以做到这一点。天啊。这不是完整的 Base64 编码,而只是更改了我们可能看到的字符:= -> %3d, & -> %26, + => %2b,/=> %2f

urlEncodedAuthString=$(printf "$authString" | sed 's/=/%3d/g' | sed 's/&/%26/g' | sed 's/+/%2b/g' | sed 's/\//%2f/g')
echo "URL encoded auth string: $urlEncodedAuthString"

通过组合基本 URL 和资源链接进行 API 调用。

url="$baseUrl$resourceLink"
echo "URL: $url"

可以使用“az rest”命令:

az rest --verbose -m $verb -u $url --headers x-ms-date="$now" x-ms-version=2018-12-31 x-ms-documentdb-isquery=true Content-Type=application/query+json Authorization=$urlEncodedAuthString --debug

替代方案:使用 cURL

curl --request $verb -H "x-ms-date: $now" -H "x-ms-version: 2018-12-31" -H "x-ms-documentdb-isquery: true" -H "Content-Type: application/query+json" -H "Authorization: $urlEncodedAuthString" $url

关于bash - 使用 bash、Azure CLI 和 REST API 访问 CosmosDB - 如何正确获取 token 和哈希?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61426902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com