【问题标题】:Failed to authenticate account level SAS in Azure无法在 Azure 中对帐户级别 SAS 进行身份验证
【发布时间】:2019-06-26 17:52:17
【问题描述】:

我一直在关注latest writeup from Microsoft,努力生成用于 Azure 存储服务(尤其是 Blob)的帐户级别共享访问签名 (SAS)。

每次我对我的 Blob 服务执行 PUT 请求时,我都会收到 403 响应,其中包含以下消息:

服务器未能验证请求。确保值 包括签名在内的授权标头格式正确。

这是我生成签名的函数:

use MicrosoftAzure\Storage\Common\Internal\StorageServiceSettings;
use MicrosoftAzure\Storage\Blob\BlobRestProxy;

public function generateUploadLink($container, $folder, $filename)
{
    # get account settings
    $settings = StorageServiceSettings::createFromConnectionString(AZURE_BLOB);
    $accountName = $settings->getName();
    $accountKey = $settings->getKey();

    # define start and expire datetime stamps (ISO 8601)
    $startTime = (new DateTime('GMT'))->modify('-2 days')->format('Y-m-d\TH:i:s\Z');
    $expireTime = (new DateTime('GMT'))->modify('+2 days')->format('Y-m-d\TH:i:s\Z');

    $parameters = [];
    $parameters[] = $accountName;       # account name
    $parameters[] = 'wac';              # permissions
    $parameters[] = 'b';                # service
    $parameters[] = 'sco';              # resource type
    $parameters[] = $startTime;         # start time
    $parameters[] = $expireTime;        # expire time
    $parameters[] = '';                 # accepted ip's
    $parameters[] = 'https,http';       # accepted protocol
    $parameters[] = '2018-03-28';       # latest microsoft api version

    # implode the parameters into a string
    $stringToSign = utf8_encode(implode("\n", $parameters));

    # decode the account key from base64
    $decodedAccountKey = base64_decode($accountKey);

    # create the signature with hmac sha256
    $signature = hash_hmac("sha256", $stringToSign, $decodedAccountKey, true);

    # encode the signature as base64
    $sig = urlencode(base64_encode($signature));

    # construct the sas (shared access signature)
    $sas = "sv=2018-03-28&ss=b&srt=sco&sp=wac&se={$expireTime}&st={$startTime}&spr=https,http&sig={$sig}";

    # create client
    $blobClient = BlobRestProxy::createBlobService(AZURE_BLOB);

    # generate upload link
    $blobUrlWithSAS = sprintf('%s%s?%s', (string)$blobClient->getPsrPrimaryUri(), "{$container}/{$folder}/{$filename}", $sas);

    # return upload link
    return $blobUrlWithSAS;
}

我的输出示例如下所示 - 当向此 URL 发出 PUT 请求时,它失败并显示上述错误消息。

https://batman.blob.core.windows.net/payroll-enroll/2019/test.txt?sv=2018-03-28&ss=b&srt=sco&sp=wac&se=2019-02-04T03:44:51Z&st=2019-01-31T03:44:51Z&spr=https,http&sig=ox7RdKGTKRYvGz2u9ScFv4TP4ZfduKxFhYdpvJKjE4A%3D

相比之下,如果我直接从 Azure 门户生成帐户级别的共享访问签名,它看起来像这样——当向这个 URL 发出 PUT 请求时,它会成功。

https://batman.blob.core.windows.net/payroll-enroll/2019/test.txt?sv=2018-03-28&ss=b&srt=sco&sp=wac&se=2019-02-02T16:29:17Z&st=2019-02-02T08:29:17Z&spr=https,http&sig=omPc4ZwEdefDoHKqA4TqVOm3NUW%2BcKcNqTuD1hq94VU%3D

除了开始时间和过期时间之外,我认为两者之间没有区别。顺便说一句,我还要注意,我曾尝试使用 azure-storage-php 包生成服务级别 SAS,但结果相同(无法验证请求)。

我已经确认或尝试过以下事情:

  • 与通过 Azure 门户看到的值相比,$accountName$accountKey 正在返回正确的值
  • 尝试将nowUTCGMT 中的每一个作为DateTime() 的参数
  • 在两侧提供了充足的填充(2 天),以确保这不是我在 Stack 上阅读的其他问题中经常提到的时差问题
  • 将通配符 (*) CORS 设置应用到我的存储帐户ALLOWED METHODSALLOWED ORIGINSALLOWED HEADERSEXPOSED HEADERS
  • 禁用Secure transfer required(同时允许httphttps

我被难住了。

我的问题:我在构建 SAS 时做错了什么,为什么我继续收到与身份验证相关的请求失败?

【问题讨论】:

    标签: php azure azure-blob-storage


    【解决方案1】:

    请更改以下代码行:

    $stringToSign = utf8_encode(implode("\n", $parameters));
    

    $stringToSign = utf8_encode(implode("\n", $parameters) . "\n");
    

    本质上,您需要附加一个额外的换行符。

    取自这里的代码:https://github.com/Azure/azure-storage-php/blob/master/azure-storage-common/src/Common/SharedAccessSignatureHelper.php

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 2019-01-26
      • 2016-11-01
      相关资源
      最近更新 更多