2017-04-20 13 views
0

投稿ごとにBLOBフォームを1つのストレージアカウントにコピーしようとしていますherex-ms-copy-sourceshared access signature (SAS)を生成することができます。今私の問題は、 "AuthenticationFailedServer failed to authenticate the request"と言うコピーブロブ操作の認証を通過できません。コピーBLOB操作のためのAzure SASトークン

コピーblobの認証トークンと認証トークンを生成するために、以下のコードを使用しています。誰かが

$date = gmdate('D, d M Y H:i:s \G\M\T'); 
$account_name = "souraccount"; 
$desaccname = "desaccount"; 
$destcontainername = "descontainer"; 
$blobname = "abc.png"; 
$sourcecontainer = "sourcecontainer"; 
$source_account_key = "asdfghjkl"; 
$destination_account_key = "poiuytr"; 

$expiry = gmdate("Y-m-d\TH:i:s\Z", time() + 30000); 
$sig = getSASForBlob($account_name,$sourcecontainer, $blobname, "b", "r", $expiry, $source_account_key); 
$url = getBlobUrl($account_name,$account_name,$blobname,"b","r",$expiry,$sig); 

$canonicalizedHeaders = "x-ms-copy-source:".$url."\nx-ms-date:$date\nx-ms-version:2015-04-05"; 
$canonicalizedResource = "/$account_name/$sourcecontainer/$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'.' '.$desaccname.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($destination_account_key), true)); 

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

$headers = [ 
    "x-ms-copy-source:$url", 
    "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); 

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

function getBlobUrl($accountName,$container,$blob,$resourceType,$permissions,$expiry,$_signature){ 
    /* Create the signed query part */ 
    $_parts = array(); 
    $_parts[] = 'sv=2015-04-05'; 
    $_parts[] = 'sr=' . $resourceType; 
    $_parts[] = 'sig=' . urlencode($_signature); 
    $_parts[] = (!empty($expiry))?'se=' . urlencode($expiry):'';  
    $_parts[] = (!empty($permissions))?'sp=' . $permissions:''; 

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

    return $_url; 
} 
+0

1つの問題は、あなたが同じキーソース&宛先の両方のアカウントのために( '$のaccount_key')を使用しているということです。 –

+0

@ GauravMantri私は、 '$ source_account_key'と' $ destination_account_key'でコードを変更しました。それでもまだ認証に失敗します – MSA

+0

私が気づいたもう一つのことがあります。あなたのリクエストヘッダーでは 'Content-Length'ヘッダーの値を' 0'(これは正しい)に設定していますが、 '$ arraysign [] 'ではこの値を空にしないでください。ここで値を「0」に設定してリクエストを再試行できますか? –

答えて

0

blobをソースストレージアカウントからコピー先ストレージアカウントにコピーするための完全な作業コードを次に示します。コメント欄にのGaurav Mantriによって与えられたソリューションは、固定私はあなたのコードで見る私の問題

$date = gmdate('D, d M Y H:i:s \G\M\T'); 
$account_name = "saccname"; // Source Storage acoount name 
$desaccname = "daccname"; // destination Storage acoount name 
$destcontainername = "vhd"; // destination Container name 
$blobname = "sblob.vhd"; // source blob name 
$sourcecontainer = "vhd"; // source container name 
$source_account_key = "sdfsdfdsf"; 
$destination_account_key = "safdsf"; 

$expiry = gmdate("Y-m-d\TH:i:s\Z", time() + 30000); 
$sig = getSASForBlob($account_name,$sourcecontainer, $blobname, "b", "r", $expiry, $source_account_key); 
$xms_copy_source_url = getBlobUrl($account_name,$sourcecontainer,$blobname,"b","r",$expiry,$sig); 

$canonicalizedHeaders = "x-ms-copy-source:".$xms_copy_source_url."\nx-ms-date:$date\nx-ms-version:2015-04-05"; 
$canonicalizedResource = "/$desaccname/$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'.' '.$desaccname.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($destination_account_key), true)); 

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

$headers = [ 
    "x-ms-copy-source:$xms_copy_source_url", 
    "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); 


function getSASForBlob($accountName,$container, $blob, $resourceType, $permissions, $expiry,$source_account_key){ 
    /* Create the signature */ 
    $_arraysign = array(); 
    $_arraysign[] = $permissions; 
    $_arraysign[] = ''; 
    $_arraysign[] = $expiry; 
    $_arraysign[] = '/blob/' . $accountName . '/' . $container . '/' . $blob; 
    $_arraysign[] = ''; 
    $_arraysign[] = ''; 
    $_arraysign[] = ''; 
    $_arraysign[] = "2015-04-05"; //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($source_account_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-04-05'; 
     $_parts[] = 'rscd='; 

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

    return $_url; 
} 
1

@Gaurav Mantriコメントに書いた問題を修正するには私を助けることができます:我々は間違いなくいくつかの進歩を作っている:)

。 SAS URLに問題があると思われます。あなたのgetSASForBlob機能に

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

に次の行

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

を変更してみてください。

関連する問題