2017-04-14 79 views
0

我試圖在同一個存儲帳戶中將blob從一個容器複製到另一個容器。 azure rest api的文檔並不清楚,也沒有說如何從源容器複製到目標容器,也沒有說明如何將blob從一個存儲帳戶複製到另一個存儲帳戶。Azure使用rest api和php在同一存儲帳戶中將blob從一個容器複製到另一個容器

我曾嘗試使用下面的代碼,它拋出一個錯誤說複製「看待AuthenticationFailedServer無法進行身份驗證的要求。確保授權頭的值是正確形成包括簽名。

$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); 
+0

'X-MS-複製source'值應該在'$ headers'和'$ canonicalizedHeaders'相同。在這兩個地方它都應該是源blob的URL。 –

+0

我試過在兩個地方都有相同的x-ms-copy-source,但它仍然不起作用給出相同的認證錯誤 – MSA

+0

還有一件事情....您在'$ canonicalizedHeaders'中的請求標頭必須按字母順序排序。所以它應該是'$ canonicalizedHeaders =「x-ms-copy-source:https://」。$ account_name。「.blob.core.windows.net /」。$ containername。「/」。$ blobname。「\ nx-ms-version:2015-04-05「;' –

回答

1
  • 請求標頭x-ms-date是必需的。它還需要在$canonicalizedHeaders中提供 。
  • 如果請求正文爲none,則可以在 請求標頭中設置Content-Length0。然後在使用2015-02-21 或更高版本時,將Content-Length部分的 $stringtosign設置爲空字符串。

請嘗試以下代碼:

<?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); 
+0

因此,將blob從一個容器複製到另一個存儲帳戶中的另一個容器工作正常。我如何將它從一個存儲帳戶複製到另一個存儲帳戶? – MSA

相關問題