我需要帮助生成正确的授权标头以在 Linux 上使用 curl 发布到 Azure 表。我对 API 和 REST 的世界感到冷漠。我一直在使用 az cli 进行合并,但在负载下它会耗尽盒子上的所有资源,因此最终目标是从 ksh 脚本中编写批量插入脚本。现在我只是想让插入工作,但如果我在错误的轨道上,任何关于批量目标的见解都将非常受欢迎。
这个问题带有 Curl 的 Azure 存储表 API REST 帮助很大,因为它是我发现的唯一一个完整的例子,它从 nix 命令行(而不是 MS 提供的所有 C# 例子)做一些非常相似的事情。 使用它,我已经能够查询 (GET) 完整表、特定实体/值等,而无需 curl -k(不安全)——一切都很好。将其转换为插入证明是有问题的。
我几乎借用了上述问题的所有内容。我唯一更改的部分是 GET>POST、accept>Content-Type、删除 Content-Length 并添加我从建议的 curl 网站下载的 cacert 文件。这是 curl 尝试...
# curl -v \
> -H "Authorization: SharedKey XXXXXXX:${signature}" \
> -H "x-ms-date: $request_date" -H "x-ms-version: 2017-07-29" \
> -H "Content-Type: application/json; charset=UTF-8" \
> --data @body.json "https://XXXXXXX.table.core.windows.net/YYYYYYY" \
> --cacert cacert.pem
* Trying <20.150.40.102>...
* TCP_NODELAY set
* Connected to XXXXXXX.table.core.windows.net (20.150.40.102) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: cacert.pem
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.table.core.windows.net
* start date: May 19 11:38:54 2020 GMT
* expire date: May 19 11:38:54 2022 GMT
* subjectAltName: host "XXXXXXX.table.core.windows.net" matched cert's "*.table.core.windows.net"
* issuer: C=US; ST=Washington; L=Redmond; O=Microsoft Corporation; OU=Microsoft IT; CN=Microsoft IT TLS CA 4
* SSL certificate verify ok.
> POST /YYYYYYY HTTP/1.1
> Host: XXXXXXX.table.core.windows.net
> User-Agent: curl/7.62.0-DEV
> Accept: */*
> Authorization: SharedKey XXXXXXX:UJs5ATaZZZZZZZZ1L3c=
> x-ms-date: Fri, 29 May 2020 13:58:52 GMT
> x-ms-version: 2017-07-29
> Content-Type: application/json; charset=UTF-8
> Content-Length: 183
>
* upload completely sent off: 183 out of 183 bytes
< HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
< Content-Length: 419
< Content-Type: application/xml
< Server: Microsoft-HTTPAPI/2.0
< x-ms-request-id: ccf4784c-4002-000a-44c1-3556f6000000
< x-ms-error-code: AuthenticationFailed
< Date: Fri, 29 May 2020 13:58:53 GMT
<
<?xml version="1.0" encoding="utf-8"?><m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code>AuthenticationFailed</m:code><m:message xml:lang="en-US">Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:ccf4784c-4002-000a-44c1-3556f6000000
* Connection #0 to host XXXXXXX.table.core.windows.net left intact
Time:2020-05-29T13:58:53.9256087Z</m:message></m:error>
第二条 ALPN 消息似乎不是问题(根据谷歌),握手看起来不错(对吧?)。所以,我认为我在证书、密钥等方面做得很好。我一定是弄乱了 string_to_sign 的格式。
所需的标题因动词而异。参考 MS 文档,他们建议以下必需的标题并说顺序很重要......
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedResource;
只需要动词,日期和佳能,所以...
POST\n\n\n${request_date}\n/XXXXXXX/YYYYYYY;
……应该没问题。但是,还有一个脚注说我需要“DataServiceVersion 和 MaxDataServiceVersion 标头”,但它没有包含在其正上方的示例中,并且没有指示这些附加字段所需的顺序。 https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key#Subheading2。
进一步谷歌搜索似乎这些实际上需要在 json 中,所以我将它们放入我的 body.json 文件中。
{
"M00":"98989898",
"PartitionKey":"20200529",
"RowKey":"sometext"
"DataServiceVersion":"3.0;NetFx"
"MaxDataServiceVersion":"3.0;NetFx"
}
额外学分... 进一步展望批处理配置,我可以看到途中有更多“乐趣”,所以如果有人从 bash/ksh/nix 命令行完成此操作,请分享。我感觉我已经接近了,但我发现很难想象我需要在命令行上构建什么,例如,当我看到这个时......
https://learn.microsoft.com/en-us/rest/api/storageservices/performing-entity-group-transactions
(那些批次和变更集 ID 从何而来??)
您的第一个问题显示为消息:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
这意味着您的 canonicalized_resource 很可能存在问题并且未正确签名,可能是因为它缺少所需的详细信息,或者存在字符,稍后 printf 在 at:
signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" -binary | base64 -w0)
首先检查 printf 没有失败:
printf "$string_to_sign"
我一直在尝试做类似的事情(使用 cURL 插入 Azure 存储表),但还没有成功,但我可以很好地查询 (GET) 表。