SAS Azure签名不匹配

时间:2016-12-08 16:34:05

标签: php azure blob

我尝试在php中为Azure上的blob创建一个SAS。 我写了以下代码:

$key ="...";

$end = date('Y-m-d\TH\:i\:s\Z', strtotime('+1 day'));

function getSASForBlob($accountName, $container, $blob, $permissions ,$expiry, $key){
 /* Create the signature */
 $_arraysign = array();
 $_arraysign[] = $permissions;
 $_arraysign[] = '';
 $_arraysign[] = $expiry;
 $_arraysign[] = '/'.$accountName . '/' . $container . '/' . $blob;
 $_arraysign[] = '';
 $_arraysign[] = "2015-12-11"; //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));
}

function getBlobUrl($accountName, $container, $blob, $resourceType, $permissions, $expiry, $_signature){
 /* Create the signed query part */
 $_parts = array();
 $_parts[] = 'sv=2015-12-11';

 $_parts[] = 'ss=b';
 $_parts[] = 'srt=' . $resourceType;
 $_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
 $_parts[] = (!empty($expiry))?'se=' .$expiry:'';
 $_parts[] = 'spr=https';
 $_parts[] = 'sig=' . urlencode($_signature);


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

 return $_url;
 }


$sig = getSASForBlob("cloudviewer","450-423-422-392", "thumbnail.jpeg", "r",     $end, $key);
$url = getBlobUrl("cloudviewer","450-423-422-392","thumbnail.jpeg","o","r", $end, $sig);

echo(json_encode(array('url' => $url, 'sig' => $sig, 'expiry' => $end)));

我收到的网址结果是:Here

出现身份验证错误:签名不匹配。使用的字符串是cloudviewer r b o 2016-12-09T17:08:25Z https 2015-12-11

我直接从Azure创建了一个SAS,我有了网址 https://cloudviewer.blob.core.windows.net/450-423-422-392/thumbnail.jpeg?sv=2015-12-11&ss=b&srt=o&sp=r&se=2016-12-09T17:08:25Z&spr=https&sig=BU6lfFljKLsmK8zPdHny5qRU9XStpE97Pud5vj4biEY%3D 它的工作原理与第一个相似。

我已经尝试了

$_arraysign[] = '/blob/'.$accountName . '/' . $container . '/' . $blob;
$_arraysign[] = $accountName . '/' . $container . '/' . $blob;

你有什么想法吗?

感谢

1 个答案:

答案 0 :(得分:0)

似乎您正在尝试生成帐户SAS令牌,如https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1#examples-of-sas-uris中所述的第二个示例。根据我的理解,您只能生成一个常见的blob SAS令牌作为上面提到的第一个示例。

同时,根据Constructing the Signature String的描述,您在生成签名时错过了几个部分。

因此,请尝试以下代码段:

function getSASForBlob($accountName, $container, $blob, $permissions ,$expiry, $key){
 /* Create the signature */
 $_arraysign = array();
 $_arraysign[] = $permissions;
 $_arraysign[] = '';
 $_arraysign[] = $expiry;
 $_arraysign[] = '/blob' .'/'.$accountName . '/' . $container . '/' . $blob;
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = '';
 $_arraysign[] = "2015-12-11"; //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));
}

function getBlobUrl($accountName, $container, $blob, $resourceType, $permissions, $expiry, $_signature){
 /* Create the signed query part */

 $_parts = array();
    $_parts[] = (!empty($expiry)) ? 'se=' . urlencode($expiry) : '';
    $_parts[] = 'sr=' . $resourceType;
    $_parts[] = (!empty($permissions)) ? 'sp=' . $permissions : '';
    $_parts[] = 'sig=' . urlencode($_signature);
    $_parts[] = 'sv=2015-12-11';
    $_parts[] = 'rscd=';


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

 return $_url;
 }

$sig = getSASForBlob(AZURE_ACC_NAME,AZURE_CONTAINER, BLOB, "r", $endDate, AZURE_PRIMARY_KEY);
$url = getBlobUrl(AZURE_ACC_NAME,AZURE_CONTAINER,BLOB,"b","r", $endDate, $sig);