首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在Azure中验证帐户级别SAS

无法在Azure中验证帐户级别SAS
EN

Stack Overflow用户
提问于 2019-02-02 09:11:47
回答 1查看 309关注 0票数 0

我一直在跟踪微软的最新报道,以便生成一个帐户级共享访问签名(SAS),用于Azure存储服务,特别是Blobs。

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

服务器无法验证请求。确保授权头的值是正确的,包括签名。

这是我生成签名的功能:

代码语言:javascript
复制
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-存储-php包生成服务级SAS (未能验证请求)。

我已经确认并或尝试了以下几点:

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

我很困惑。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-02 13:30:29

请更改以下代码行:

代码语言:javascript
复制
$stringToSign = utf8_encode(implode("\n", $parameters));

代码语言:javascript
复制
$stringToSign = utf8_encode(implode("\n", $parameters) . "\n");

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54491594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档