简体   繁体   English

使用 php 的 Azure 共享访问签名错误

[英]Azure Shared Access Signature error using php

I'm using SAS to trying to download a blob from a Private Azure Storage container, using php.我正在使用 SAS 尝试使用 php 从私有 Azure 存储容器下载 blob。 But ALWAYS it throws me the same mistake.但它总是让我犯同样的错误。

<Error>
<Code>AuthenticationFailed</Code>
<Message>
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. ...
</Message>
<AuthenticationErrorDetail>
Signature did not match. String to sign used ... /blob/name/container/archive.jpg
</AuthenticationErrorDetail>
</Error>

This is my code:这是我的代码:

static private function getSASForBlob($accountName,$containerName, $fileName, $resourceType, $permissions, $expiry) {
     /* Create the signature */         

        $_arraysign = array();
        $_arraysign[] = $permissions;
        $_arraysign[] = '';
        $_arraysign[] = $expiry;
        $_arraysign[] = $accountName . '/' . $containerName . '/' . $fileName;
        $_arraysign[] = '';
        $_arraysign[] = "2015-04-05"; //the API version is now required
        $_arraysign[] = '';
        $_arraysign[] = '';
        $_arraysign[] = '';
        $_arraysign[] = '';
        $_arraysign[] = '';

        $_str2sign = implode("\n", $_arraysign);

        return base64_encode(
        hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($key), true)
    );
    }
    static public function getBlobDownloadUrl($container,$blob,$accountName,$key){
 /* Create the signed query part */         
        $resourceType='b';
        $permissions='r';
        /*$expTime_utc = new DateTime(null, new DateTimeZone("UTC"));
        $expTime_utc->add(new DateInterval('PT1H'));
        $expiry=$expTime_utc->format('Y-m-d\TH:i:s\Z');*/
        $expiry = date('Y-m-d\TH:i:s\Z', strtotime('+1 day'));
        $_signature=AzureServices::getSASForBlob($accountName,$key,$container, $blob, $resourceType, $permissions, $expiry);
        $_parts = array();
        $_parts[] = (!empty($expiry))?'se=' . urlencode($expiry):'';
        $_parts[] = 'sr=' . $resourceType;
        $_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
        $_parts[] = 'sig=' . urlencode($_signature);
        $_parts[] = "sv=2015-04-05";

        /* Create the signed blob URL */
        $_url = 'https://'
        .$accountName.'.blob.core.windows.net/'
        . $container . '/'
        . $blob . '?'
        . implode('&', $_parts);

        return $_url;
    }

I have tried changing the date to DateTime following the same structure, adding and deleting an "/" to the line "$_arraysign[] = $accountName . '/' . $containerName . '/' . $fileName" ... But nothing happened, the same error message is showed... Please help me.我尝试按照相同的结构将日期更改为 DateTime,在“$_arraysign[] = $accountName . '/' . $containerName . '/' . $fileName” 行中添加和删除“/”...但是什么也没发生,显示相同的错误消息...请帮助我。 Thanks谢谢

As you are using the signedversion in 2015-04-05 , so beside @Gaurav Mantri's answer, there is one more point you need to be attention to, is that, according the description under section Constructing the Signature String in https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx :由于您使用的是2015-04-05signedversion ,因此除了@Gaurav Mantri 的回答之外,您还需要注意一点,即,根据https://msdn 中构建签名字符串部分下的描述.microsoft.com/en-us/library/azure/dn140255.aspx

Version 2015-04-05 adds support for the signed IP and signed protocol fields.版本 2015-04-05 添加了对签名 IP 和签名协议字段的支持。 These must be included in the string-to-sign.这些必须包含在要签名的字符串中。 To construct the string-to-sign for Blob or File service resources, use the following format:要为 Blob 或文件服务资源构造要签名的字符串,请使用以下格式:

StringToSign = signedpermissions + "\n" +
           signedstart + "\n" +
           signedexpiry + "\n" +
           canonicalizedresource + "\n" +
           signedidentifier + "\n" +
           signedIP + "\n" +
           signedProtocol + "\n" +
           signedversion + "\n" +
           rscc + "\n" +
           rscd + "\n" +
           rsce + "\n" +
           rscl + "\n" +
           rsct

So we need to modify the $_arraysign in function getSASForBlob to something like:所以我们需要将函数getSASForBlob$_arraysign修改为:

$_arraysign = array();
$_arraysign[] = $permissions;
$_arraysign[] = '';
$_arraysign[] = $expiry;
$_arraysign[] = '/blob/' . $accountName . '/' . $container . '/' . $blob;
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = "2015-04-05"; //the API version is now required
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';
$_arraysign[] = '';

Any further concern, please feel free to let me know.任何进一步的问题,请随时告诉我。

Please prepend /blob/ in this line of code:请在这行代码中添加/blob/

$_arraysign[] = $accountName . '/' . $containerName . '/' . $fileName;

So, it should be:所以,应该是:

$_arraysign[] = '/blob/' . $_arraysign[] = '/blob/' 。 $accountName . $账户名。 '/' . '/' 。 $containerName . $容器名称。 '/' . '/' 。 $fileName; $文件名;

From this page: https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx从此页面: https : //msdn.microsoft.com/en-us/library/azure/dn140255.aspx

The canonicalizedresouce portion of the string is a canonical path to the signed resource.字符串的规范化资源部分是签名资源的规范路径。 It must include the service name (blob, table, queue or file) for version 2015-02-21 or later, the storage account name, and the resource name, and must be URL-decoded .它必须包含 2015-02-21 或更高版本的服务名称(blob、表、队列或文件)、存储帐户名称和资源名称,并且必须是 URL 解码的 Names of blobs must include the blob's container. blob 的名称必须包含 blob 的容器。 Table names must be lower-case.表名必须小写。 The following examples show how to construct the canonicalizedresource portion of the string, depending on the type of resource.以下示例显示如何根据资源类型构造字符串的规范化资源部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM