【问题标题】:Azure Copy blobs from one container to another in same storage account using rest api and phpAzure 使用 rest api 和 php 将 blob 从一个容器复制到同一存储帐户中的另一个容器
【发布时间】:2017-09-10 19:30:25
【问题描述】:

我正在尝试将 blob 从一个容器复制到同一存储帐户中的另一个容器。 azure rest api 的文档不清楚,也没有说明如何从源容器复制到目标容器以及如何将 blob 从一个存储帐户复制到另一个存储帐户。

我尝试使用以下代码复制 blob,它会引发错误,提示“AuthenticationFailedServer 未能对请求进行身份验证。确保 Authorization 标头的值正确形成,包括签名。” p>

$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";    
$account_key = "asdf";

$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.window‌​s.net/".$sourcecontainer."/".$blobname."\n‌​x-ms-version:2015-04‌​-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";


$arraysign = array();
$arraysign[] = 'PUT';                     /*HTTP Verb*/  
$arraysign[] = '';                        /*Content-Encoding*/  
$arraysign[] = '';                        /*Content-Language*/  
$arraysign[] = 1;                        /*Content-Length (include value when zero)*/  
$arraysign[] = '';                        /*Content-MD5*/  
$arraysign[] = '';                        /*Content-Type*/  
$arraysign[] = '';                        /*Date*/  
$arraysign[] = '';                        /*If-Modified-Since */  
$arraysign[] = '';                        /*If-Match*/  
$arraysign[] = '';                        /*If-None-Match*/  
$arraysign[] = '';                        /*If-Unmodified-Since*/  
$arraysign[] = '';                        /*Range*/  
$arraysign[] = $canonicalizedHeaders;     /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource;    /*CanonicalizedResource*/

$stringtosign = implode("\n", $arraysign);
$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));

$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$containername.'/blob.png'; 

$headers = [
    'x-ms-copy-source:https://'.$account_name.'.blob.core.window‌​s.net/'.$sourcecontainer.'/'.$blobname.'',
    //"x-ms-date:{$date}",
    'x-ms-version:2015-04-05',
    'Accept:application/json;odata=nometadata',
    'Accept-Charset:UTF-8',
    'Content-Length:1',
    "Authorization:{$signature}"
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
$response  = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);        

echo '<pre>';print_r($response);

【问题讨论】:

  • x-ms-copy-source 的值在$headers$canonicalizedHeaders 中应该相同。在这两个地方,它都应该是源 blob 的 URL。
  • 我尝试在两个地方都使用相同的 x-ms-copy-source,但仍然无法正常工作并给出相同的身份验证错误
  • 还有一件事....$canonicalizedHeaders 中的请求标头必须按字母顺序排序。所以应该是$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$containername."/".$blobname."\nx-ms-version:2015-04-05";
  • 我试过了,不行。给出相同的错误消息“服务器无法对请求进行身份验证。确保 Authorization 标头的值格式正确,包括签名。”
  • 您是否可以使用您正在使用的最新代码更新您的问题。我在想你错过了一些非常小的东西。

标签: php azure authentication azure-blob-storage


【解决方案1】:
  • 请求标头x-ms-date 是必需的。也需要呈现 在$canonicalizedHeaders
  • 如果请求体为none,可以在中设置Content-Length0 请求标头。然后设置Content-Length部分 $stringtosign 使用版本 2015-02-21 时为空字符串 或更晚。

请尝试以下代码:

<?php

$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";    
$account_key = "asdf";

$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$sourcecontainer."/".$blobname."\nx-ms-date:$date\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";

$arraysign = array();
$arraysign[] = 'PUT';                     /*HTTP Verb*/  
$arraysign[] = '';                        /*Content-Encoding*/  
$arraysign[] = '';                        /*Content-Language*/  
$arraysign[] = '';                        /*Content-Length (include value when zero)*/  
$arraysign[] = '';                        /*Content-MD5*/  
$arraysign[] = '';                        /*Content-Type*/  
$arraysign[] = '';                        /*Date*/  
$arraysign[] = '';                        /*If-Modified-Since */  
$arraysign[] = '';                        /*If-Match*/  
$arraysign[] = '';                        /*If-None-Match*/  
$arraysign[] = '';                        /*If-Unmodified-Since*/  
$arraysign[] = '';                        /*Range*/  
$arraysign[] = $canonicalizedHeaders;     /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource;    /*CanonicalizedResource*/

$stringtosign = implode("\n", $arraysign);

$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));

$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$destcontainername.'/'.$blobname;

$headers = [
    'x-ms-copy-source:https://'.$account_name.'.blob.core.windows.net/'.$sourcecontainer.'/'.$blobname,
    "x-ms-date:{$date}",
    'x-ms-version:2015-04-05',
    'Accept:application/json;odata=nometadata',
    'Accept-Charset:UTF-8',
    'Content-Length:0',
    "Authorization:{$signature}"
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
$response  = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);        

echo '<pre>';print_r($response);

【讨论】:

  • 因此,将 blob 从一个容器复制到同一存储帐户中的另一个容器可以正常工作。如何将 blob 从一个存储帐户复制到同一订阅中的另一个帐户?
猜你喜欢
  • 2015-10-22
  • 1970-01-01
  • 2020-03-29
  • 2023-04-06
  • 2020-07-21
  • 2021-06-27
  • 2021-08-25
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多