用于 blob 的 Azure PHP SAS

Posted

技术标签:

【中文标题】用于 blob 的 Azure PHP SAS【英文标题】:Azure PHP SAS for blob 【发布时间】:2016-05-29 00:36:35 【问题描述】:

我正在尝试为我的天蓝色 blob 存储创建一个 SAS,但我收到的消息是我的签名字段格式不正确。

首先是一个创建签名的函数:

function getSASForBlob($accountName,$container, $blob, $resourceType, $permissions, $expiry,$key)

    /* Create the signature */
    $_arraysign = array();
    $_arraysign[] = $permissions;
    $_arraysign[] = '';
    $_arraysign[] = $expiry;
    $_arraysign[] = '/' . $accountName . '/' . $container . '/' . $blob;
    $_arraysign[] = '';
    $_arraysign[] = "2014-02-14"; //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)
    );

然后是一个为我提供 URL 的函数:

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=2014-02-14';

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

    return $_url;

然后我调用函数并指定参数。

$container = '87d57f73-a327-4344-91a4-27848d319a66';
$blob = '8C6CBCEB-F962-4939-AD9B-818C124AD3D9.mp4';
$endDate = date('YYYY-MM-DDThh:mmTZD', strtotime('+1 day'));

$_signature = getSASForBlob($accountName,$container,$blob,'b','r',$endDate,$accountKey);
$_blobUrl = getBlobUrl($accountName,$container,$blob,'b','r',$endDate,$_signature);

https://ttresources.blob.core.windows.net/87d57f73-a327-4344-91a4-27848d319a66/8C6CBCEB-F962-4939-AD9B-818C124AD3D9.mp4?se=2016201620162016-FebFeb-ThuThuCET1111%3A0202CET3600Thu&sr=b&sp=r&sig=1VdOjLX179wLQv5o265JBR%2B6CaLTr1nwCs6GHSVqfbA%3D&sv=2014-02-14

这是我得到的结果,当我关注它时,我会收到下一条错误消息:

AuthenticationFailed 服务器失败 验证请求。确保 Authorization 标头的值 格式正确,包括签名。 请求 ID:41f089a3-0001-0027-376f-6966d1000000 时间:2016-02-17T10:38:00.2724783Z 签名字段不好 形成。

【问题讨论】:

【参考方案1】:

您构建canonicalizedresource 的方式存在问题。请从此行中删除 $accountName 之前的 /

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

应该是这样的:

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

基于文档here

URL = https://myaccount.blob.core.windows.net/music/intro.mp3 
canonicalizedresource = "myaccount/music/intro.mp3"

【讨论】:

通过此修改仍然得到相同的结果 我注意到的另一件事是您的 URL (2016201620162016-FebFeb-ThuThuCET1111%3A0202CET3600Thu) 中的 se 参数。您能否检查一下您是否为 SAS Expiry 传递了正确的值?【参考方案2】:

因为问题是您设置了错误的日期时间格式。根据guide:

signedstart 和 signedexpiry 字段必须以 UTC 时间表示,并且必须遵循有效的 ISO 8601 格式。支持的 ISO 8601 格式包括:

YYYY-MM-DD YYYY-MM-DDThh:mmTZD YYYY-MM-DDThh:mm:ssTZD

php 中,您应该按以下格式创建日期时间:

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

那么它将是正确的格式。

【讨论】:

以上是关于用于 blob 的 Azure PHP SAS的主要内容,如果未能解决你的问题,请参考以下文章

Azure SAS 令牌不适用于 Azure.Storage.Blobs BlobServiceClient

Azure Blob PHP SDK - 直接从自定义多部分 API 请求上传到 Azure 存储

用于访问 Azure 存储中的私有 blob 的 URL

用于读取 blob 架构的 Azure 函数

使用 php 从子目录中获取 azure blob 文件

用于复制到 Azure Blob 的 Azure SAS 授权参数是啥?