2014-10-20 83 views
1

我試圖使用PHP創建SAS鏈接到blob資源。不幸的是,目前在Azure SDK中沒有創建SAS簽名的方法。 我寫了一個代碼來生成SAS,但當我試圖通過此方法生成的鏈接獲取資源時,我收到此消息:簽名字段結構不正確。Microsoft Azure和SAS for PHP

public function getSharedAccessSignatureURL($container, $blob) 
{ 
    $signedStart = date('c', strtotime('-1 day')); 
    $signedExpiry = date('c', strtotime('+1 day')); 
    $signedResource = 'b'; 
    $signedPermission = 'r'; 
    $signedIdentifier = ''; 
    $responseContent = "file; attachment"; 
    $responseType = "binary"; 

    $canonicalizedResource = '/'.$this->account['accountName'].'/'.$container.'/'.$blob; 
    $signedVersion = '2014-02-14'; 

    $stringToSign = 
     $signedPermission."\n". 
     $signedStart."\n". 
     $signedExpiry."\n". 
     $canonicalizedResource."\n". 
     $signedIdentifier."\n". 
     $signedVersion; 

    $signature = base64_encode(
     hash_hmac(
      'sha256', 
      urldecode(utf8_encode($stringToSign)), 
      $this->account['primaryKey'], 
      true 
     ) 
    ); 

    $arrayToUrl = [ 
     'sv='.urlencode($signedVersion), 
     'st='.urlencode($signedStart), 
     'se='.urlencode($signedExpiry), 
     'sr='.urlencode($signedResource), 
     'sp='.urlencode($signedPermission), 
     'rscd='.urlencode($responseContent), 
     'rsct='.urlencode($responseType), 
     'sig='.urlencode($signature) 
    ]; 

    $url = 'https://'.$this->account['accountName'].'.blob.core.windows.net'.'/' 
     .$container.'/' 
     .$blob.'?'.implode('&', $arrayToUrl); 

    return $url; 
} 

任何暗示我做錯了什麼?我是微軟Azure的新手

+0

你先google嗎? https://social.msdn.microsoft.com/Forums/en-US/03979c33-dc9d-4711-8f8a-fce1a5ebc476/getting-random-exception-while-downloading-blobs?forum=windowsazuremanagement。只是好奇 - – ChrisG 2014-10-20 19:08:02

+0

是的。但是PHP並沒有太多的功能。我真的不明白,特別是我嘗試按照文檔。 http://msdn.microsoft.com/en-US/library/azure/dn140255.aspx 有經驗的任何建議嗎? – bliszka 2014-10-20 22:54:33

回答

3

我相信你的$stringToSign變量存在問題。基於文檔在這裏:http://msdn.microsoft.com/en-US/library/azure/dn140255.aspx,你串籤應當建立類似如下:

StringToSign = signedpermissions + "\n" 
       signedstart + "\n" 
       signedexpiry + "\n" 
       canonicalizedresource + "\n" 
       signedidentifier + "\n" 
       signedversion + "\n" 
       rscc + "\n" 
       rscd + "\n" 
       rsce + "\n" 
       rscl + "\n" 
       rsct 

考慮你,包括你的SAS查詢字符串rscdrsct。請嘗試以下,看看是否是有差別:

$stringToSign = 
      $signedPermission."\n". 
      $signedStart."\n". 
      $signedExpiry."\n". 
      $canonicalizedResource."\n". 
      $signedIdentifier."\n". 
      $signedVersion."\n". 
      "\n". 
      $responseContent."\n". 
      "\n". 
      "\n". 
      $responseType; 

UPDATE

請嘗試以下的代碼。用適當的值替換帳戶名/關鍵,容器名稱和BLOB名稱:

<?php 
$signedStart = gmdate('Y-m-d\TH:i:s\Z', strtotime('-1 day')); 
echo $signedStart."\n"; 
$signedExpiry = gmdate('Y-m-d\TH:i:s\Z', strtotime('+1 day')); 
echo $signedExpiry."\n"; 
$signedResource = 'b'; 
$signedPermission = 'r'; 
$signedIdentifier = ''; 
$accountName = "[account name]"; 
$accountKey = "[account key]"; 
$container = "[container name]"; 
$blob = "[blob name]"; 
$canonicalizedResource = '/'.$accountName.'/'.$container.'/'.$blob; 
$signedVersion = '2014-02-14'; 
echo $canonicalizedResource."\n"; 
$rscc = ''; 
$rscd = 'file; attachment';//Content disposition 
$rsce = ''; 
$rscl = ''; 
$rsct = 'binary';//Content type 
$stringToSign = 
       $signedPermission."\n". 
       $signedStart."\n". 
       $signedExpiry."\n". 
       $canonicalizedResource."\n". 
       $signedIdentifier."\n". 
       $signedVersion."\n". 
       $rscc."\n". 
       $rscd."\n". 
       $rsce."\n". 
       $rscl."\n". 
       $rsct; 


echo $stringToSign."\n"; 

$signature = base64_encode(
     hash_hmac(
      'sha256', 
      $stringToSign, 
      base64_decode($accountKey), 
      true 
     ) 
    ); 

echo $signature."\n"; 


$arrayToUrl = [ 
     'sv='.urlencode($signedVersion), 
     'st='.urlencode($signedStart), 
     'se='.urlencode($signedExpiry), 
     'sr='.urlencode($signedResource), 
     'sp='.urlencode($signedPermission), 
     'rscd='.urlencode($rscd), 
     'rsct='.urlencode($rsct), 
     'sig='.urlencode($signature) 
    ]; 

    $url = 'https://'.$accountName.'.blob.core.windows.net'.'/' 
     .$container.'/' 
     .$blob.'?'.implode('&', $arrayToUrl); 

echo $url."\n"; 
?> 

基本上有兩個問題(除了不正確$stringToSign變量):

  1. 開始/結束日期時間不正確格式化。
  2. 我們需要base64_decode用於計算簽名的賬戶密鑰。
+0

「Signature fields not well formed」沒有區別。我不需要rscd,rsct參數,如果它改變了stringTosign中的任何內容? – bliszka 2014-10-21 10:16:22

+0

你能打印你的$ stringToSign變量嗎? – 2014-10-21 10:22:57

+0

我要註冊的字符串: r \ n2014-10-20T12:34:40 + 02:00 \ n2014-10-22T12:34:40 + 02:00 \ n/accountname/new/invoice.pdf \ n \ n2014 -02-14 \ n \ nfile的;附件\ n \ n \ nbinary – bliszka 2014-10-21 10:36:18