【问题标题】:Azure table service: authorize in REST API from PerlAzure 表服务:在 Perl 的 REST API 中授权
【发布时间】:2020-12-29 23:59:41
【问题描述】:

我正在尝试通过我的 Perl 脚本通过 REST API 在 Azure 表中进行授权。根据MSDN documents 并基于我对类似任务的了解(我为 Blob 服务创建了一个类似的脚本并且效果很好)我开发了一个简单的脚本:

use strict;
use warnings;

use Digest::SHA qw(hmac_sha256_base64);
use HTTP::Date;
use HTTP::Request;
use LWP::UserAgent;
use MIME::Base64;


my $account = 'myaccount';
my $key = 'Nf2b/ZSY+a...7ZT0Q==';
my $decoded_key = decode_base64( $key );

my $uri = "https://$account.table.core.windows.net/?restype=service&comp=properties";
my $method = 'GET';

my $req = HTTP::Request->new($method, $uri);

my $date = time2str();

    
my $canonicalized_resource = "/$account/\nrestype:service\ncomp:properties";

my $string_to_sign =
    "$method\n" .
    "\n" . # content-md5
    "\n" . # content-type
    "$date\n".
    $canonicalized_resource;
        

my $sig = hmac_sha256_base64($string_to_sign, $decoded_key );
$sig .= '=' x (4 - (length($sig) % 4));

$req->authorization("SharedKey $account:$sig");
$req->header('x-ms-version', '2019-02-02');
$req->header('x-ms-date', $date);
$req->date($date);

my $ua = LWP::UserAgent->new();
my $resp = $ua->request($req);

unless($resp->is_success){
    die "Request failed: " . $resp->status_line . ". Signed string: " . $string_to_sign;
}

任务很简单:通过获取Table service properties 检查我的代码。不幸的是,它不起作用!我得到:

请求失败:403 服务器未能验证请求。确保 Authorization 标头的值格式正确,包括签名。

【问题讨论】:

  • 我不熟悉 Azure,但根据docs 看来$string_to_sign 缺少一些项目(如内容编码)..

标签: azure rest perl


【解决方案1】:

SharedKey 不正确。但是,我不熟悉 Perl。您可以使用 C# 引用 example

请检查您的CanonicalizedResource 字符串:

  1. 以空字符串 ("") 开头,附加正斜杠 (/),后跟拥有所要资源的帐户的名称 访问。

  2. 附加资源的编码 URI 路径,不带任何查询参数。

  3. 检索资源 URI 上的所有查询参数,包括 comp 参数(如果存在)。

  4. 将所有参数名称转换为小写。

  5. 按参数名称按字典顺序升序对查询参数进行排序。

  6. 对每个查询参数名称和值进行 URL 解码。

  7. 在每个名称-值对之前包含一个换行符 (\n)。

  8. 将每个查询参数名称和值附加到以下格式的字符串中,确保在每个查询参数之间包含冒号 (:) 名称和值:parameter-name:parameter-value

  9. 如果查询参数有多个值,则按字典顺序对所有值进行排序,然后将它们包含在逗号分隔的列表中: parameter-name:parameter-value-1,parameter-value-2,parameter-value-n

【讨论】:

  • 谢谢!表服务与 Blob 有点不同,所以 CanonicalizedResource 也不同。更改后我的脚本可以正常工作:my $canonicalized_resource = "/$account/?comp=properties";。看起来与 Blob 不同,但有效。 C# 示例对我帮助很大!
  • 很高兴知道这一点。我在 Canonicalized Resources 中找到了一个 blog,它显示了相同的示例:GET https://<account-name>.table.core.windows.net/?restype=service&comp=properties HTTP/1.1 这里的规范化资源将是 /myaccount/?comp=properties
猜你喜欢
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 2021-07-17
  • 2021-10-20
  • 2016-05-31
  • 2021-12-08
相关资源
最近更新 更多