代码之家  ›  专栏  ›  技术社区  ›  Crayons

无法在Azure中验证帐户级别SA

  •  0
  • Crayons  · 技术社区  · 7 年前

    我一直在跟踪 latest writeup from Microsoft 为了生成一个帐户级的共享访问签名(SAS),以便与Azure存储服务(特别是Blob)一起使用。

    每次我表演 PUT 请求我的blob服务,我收到 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时失败,并显示上述错误消息。

    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,它成功。

    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 结果相同的包( 无法验证请求 )

    我已确认并或尝试以下事项:

    • $accountName $accountKey 正在返回正确的值,与通过Azure门户看到的值相比
    • 尝试每一个 now , UTC GMT 作为参数 DateTime()
    • 在每一侧提供足够的填充(2天),以确保它不是时间差问题,正如我在堆栈上读到的其他问题中经常提到的那样。
    • 应用的通配符( * )我的存储帐户的CORS设置 ALLOWED METHODS , ALLOWED ORIGINS , ALLOWED HEADERS EXPOSED HEADERS
    • 残疾人 Secure transfer required (允许两者兼而有之) http https )

    我被难住了。

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Gaurav Mantri    7 年前

    请更改以下代码行:

    $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 .

    推荐文章