0

如此所述,Azure SDK for PHP 不支持共享访问签名。所以我开发了自己的函数来使用 Miscrosoft Azure 文档(这里)和 PHPAzure Codeplex 项目和源代码(这里)生成签名 URL

我想生成一个签名的 url,可以使用开发的软件客户端直接在 Web 浏览器中调用。

我生成的签名 URL 总是返回一个“AuthenticationFailed”,详细信息“签名不匹配。签名不匹配。使用的签名字符串是 r 2013-11-03 2013-11-05 /ntgstblog/netgemvno netgemvno_default_policy”

这是我的源代码,用于生成共享访问签名和我的签名 url。你能帮我调试一下吗?

    $config = array(
         'blob_account'   => <mystroage_accountname>,
         'blob_key'       => <mystroage_accesskey>,
         'blob_protocol'  => 'http'
    );

    $_id = 'netgemvno_default_policy';

    ...

    /* Define the policy of the container */
    $_data = array(
        'SignedIdentifier' => array (
            'Id' => $_id,
            'AccessPolicy' => array(
                'Start' => date("Y-m-d", strtotime('-1 years')),
                'Expiry' => date("Y-m-d", strtotime('+1 year')),
                'Permission' => 'r'
            )
        )
    );
    $_containerAcl = ContainerAcl::create(PublicAccessType::NONE, $_data);
    $rest->blob_service->setContainerAcl($oem, $_containerAcl);

    ...

    /* get shared access url to my private blob */       
    $_start = date('Y-m-d', strtotime('-1 day'));
    //$_start = '';
    $_expiry = date('Y-m-d', strtotime('+1 day'));
    //$_expiry = '';
    $_permission = 'r';
    $_container = 'netgemvno';
    $_blob = strtolower(
        "netgemvno/backup/2013/10/29/20131029_ack.log"
    );

    /* Create the signature */
    $_arraysign = array();
    $_arraysign[] = $_permission;
    $_arraysign[] = $_start;
    $_arraysign[] = $_expiry;
    $_arraysign[] = '/' . $config['blob_account'] . '/' . $_container;
    $_arraysign[] = $_id;
    $_str2sign = implode("\n", $_arraysign);
    $_signature = base64_encode(
        hash_hmac('sha256', $_str2sign, $config['blob_key'], true)
    );

    /* Create the signed query part */
    $_parts = array();
    $_parts[] = (!empty($_start))?'st=' . urlencode($_start):'';
    $_parts[] = (!empty($_expiry))?'se=' . urlencode($_expiry):'';
    $_parts[] = (!empty($_permission))?'sp=' . $_permission:'';
    $_parts[] = 'sr=' . 'c';
    $_parts[] = (!empty($_id))?'si=' . urlencode($_id):'';
    $_parts[] = 'sig=' . urlencode($_signature);

    /* Create the signed blob URL */
    $_url = $config['blob_protocol'] . '://'
        . $config['blob_account'] . '.blob.core.windows.net/'
        . $_blob . '?'
        . implode('&', $_parts);

    return $_url;
  • 生成签名时出了什么问题?
  • 是否有任何信息丢失或无效?
  • 我是否需要使用我的存储密钥进行散列?
4

2 回答 2

0

假设您将帐户密钥存储为 base64 编码(类似于AmSacgtnBFBvyqPHTNfpThcBCFWqzE3PIl09Pr1IQBGNjln1a8fZeUTs0+fehSmGt6ujf/7DQ51ef+DEXEZziA==),请尝试更改以下代码行:

$_signature = base64_encode(
        hash_hmac('sha256', $_str2sign, $config['blob_key'], true)
    );

$_signature = base64_encode(
        hash_hmac('sha256', $_str2sign, base64_decode($config['blob_key']), true)
    );
于 2013-11-04T12:03:41.183 回答
0

我想为这篇文章提供一些额外的信息,以反映自发表这篇文章以来对 Azure REST API 所做的用于访问容器/blob 的更改。根据文档,截至 2014 年 9 月,我不得不做更多的工作。

这是 SAS 生成代码,它适用于我将 blob 上传到 PHP 中的私有容器:

private function testSASGeneration($container, $blob, $resourceType, $permissions, $start, $expiry){

     /* Create the signature */
    $_arraysign = array();
    $_arraysign[] = $permissions;
    $_arraysign[] = $start;
    $_arraysign[] = $expiry;
    $_arraysign[] = '/' . $this->blobServiceAccountName . '/' . $container;
    $_arraysign[] = '';
    $_arraysign[] = "2013-08-15"; //the API version is now required
    $_arraysign[] = '';
    $_arraysign[] = "file; attachment";
    $_arraysign[] = '';
    $_arraysign[] = '';
    $_arraysign[] = 'binary';

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

    //signature requires url decode and utf-8 encode, as illustrated in docs linked in this post.
    $_signature = base64_encode(
        hash_hmac('sha256', urldecode(utf8_encode($_str2sign)), base64_decode($this->blobServicePrimaryKey), true)
    );

     /* Create the signed query part */
    $_parts = array();
    $_parts[] = (!empty($start))?'st=' . urlencode($start):'';
    $_parts[] = (!empty($expiry))?'se=' . urlencode($expiry):'';
    $_parts[] = 'sr=' . $resourceType;
    $_parts[] = (!empty($permissions))?'sp=' . $permissions:'';
    $_parts[] = (!empty($permissions))?'rscd=' . urlencode("file; attachment"):'';
    $_parts[] = (!empty($permissions))?'rsct=' . urlencode("binary"):'';


    //$_parts[] = (!empty($_id))?'si=' . urlencode($_id):'';
    $_parts[] = 'sig=' . urlencode($_signature);
    $_parts[] = 'sv=2013-08-15'; //addition of API version in query

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

    return $_url;

}

希望这可以帮助任何被迫使用 PHP 与 Azure 通信的人,因为与 C# 对应的 API 相比,该 API 严重缺乏。

于 2014-09-26T21:04:12.913 回答