Azure Storage Table API REST with Curl on Linux



我需要帮助生成正确的授权标头,以便在 Linux 上使用 curl 发布到 Azure 表。我对API和REST的世界很冷淡。我一直在使用 az cli 进行合并,但在负载下它会占用盒子上的所有资源,因此最终目标是从 ksh 脚本中编写批量插入脚本。目前,我只是想让插入工作,但是如果我走错了轨道,那么对批处理目标的任何见解都将非常受欢迎。

这个问题 Azure 存储表 API REST with Curl 有很大帮助,因为它是我发现的唯一一个从 nix 命令行执行非常相似操作的完整示例(而不是 MS 提供的所有 C# 示例(。 使用它,我已经能够查询(GET(完整的表,特定的实体/值等,而无需curl -k(不安全( - 一切都很好。事实证明,将其转换为插入物是有问题的。

我几乎从上面的问题中借用了所有内容。我唯一更改的是GET>POST,accept>Content-Type,删除了Content-Length并添加了我从建议的curl网站下载的cacert文件。这是卷曲尝试...

# 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;

只需要动词,日期和佳能,所以...

POSTnnn${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 在以下位置有问题的字符:

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( 表。

最新更新