2016-11-27 68 views
1

我正在生成預先簽名的URL以允許用戶從S3存儲桶下載文件。我使用下面的代碼通過PHP SDK生成的URL:訪問被拒絕 - 使用預先簽名的URL的S3資源 - PHP SDK

public static function get_content_link($bucket, $key) { 

    //check response code from AWS 
    require_once 'aws/aws-autoloader.php'; 

    $s3 = new Aws\S3\S3Client([ 
     'version' => 'latest', 
     'region' => 'eu-west-1', 
     'credentials' => [ 
      'key' => 'MY-KEY', 
      'secret' => 'MY-SECRET', 
     ], 
    ]); 

    $cmd = $s3->getCommand('GetObject', [ 
     'Bucket' => $bucket, 
     'Key' => $key 
    ]); 

    $request = $s3->createPresignedRequest($cmd, '+500 minutes'); 

    // Get the actual presigned-url 
    $presignedUrl = (string) $request->getUri(); 

    return $presignedUrl; 
} 

的網址會被返回如預期,例如:

https://s3-eu-west-1.amazonaws.com/MY-BUCKET-NAME/product/3166_1480009917388.mov?x-amz-content-sha256=unsigned-payload&x-amz-algorithm=aws4-hmac-sha256&x-amz-credential=akiaiqrmkn276hcpjkaq%2f20161127%2feu-west-1%2fs3%2faws4_request&x-amz-date=20161127t145603z&x-amz-signedheaders=host&x-amz-expires=30000&x-amz-signature=98eaef504f053ca56908ac49c6539c4a8b8e250d7d3a4a12460f4a806ec41c19 

當我嘗試打開任何返回的鏈接瀏覽器我從S3獲得拒絕訪問錯誤:

<Error> 
    <Code>AccessDenied</Code> 
    <Message>Access Denied</Message> 
    <RequestId>A37839BB23186F72</RequestId> 
    <HostId> 
yvKTN+CN1TTNk2tqoxxm3MPOGTUSMaRYtbbEFeCzGP7ou5IYf37Z9uBESwUQWDIUR1GUuPbZyuM= 
    </HostId> 
</Error> 

,我想提供接入是其中包含文件夾允許公衆訪問桶中的文件,由我想要的文件夾訪問是私有的(稱爲/ product /)。我們斗的政策是這樣的:

{ 
     "Version": "2008-10-17", 
     "Statement": [ 
      { 
       "Sid": "AllowPublicReadProxies", 
       "Effect": "Allow", 
       "Principal": { 
        "AWS": "*" 
       }, 
       "Action": "s3:GetObject", 
       "Resource": "arn:aws:s3:::MY-BUCKET-NAME/proxies*" 
      }, 
      { 
       "Sid": "AllowPublicReadThumbs", 
       "Effect": "Allow", 
       "Principal": { 
        "AWS": "*" 
       }, 
       "Action": "s3:GetObject", 
       "Resource": "arn:aws:s3:::MY-BUCKET-NAME/thumbs*" 
      } 
     ] 
    } 

這是我的理解,創造一個預簽名URL的目的是允許未授權的用戶受保護的文件的臨時訪問,而無需修改桶或文件夾的權限。

有沒有人有任何想法,我已經錯過或做錯了?

謝謝!

+1

您在哪裏授予與此AWS Access Key Id關聯的IAM用戶執行's3:GetObject'所需的權限? –

+1

您是否可以嘗試使用[AWS Command-Line Interface(CLI)](http://aws.amazon.com/cli/)生成預簽名的URL來確認權限是否有效?要使用的命令是['aws s3 presign'](http://docs.aws.amazon.com/cli/latest/reference/s3/presign.html)。然後,比較這些網址以確保所有元素都匹配(但值會有所不同)。您提供的網址中的「過期」時間似乎不正確。預先簽名的URL不依賴存儲桶策略 - 它是提供訪問權限的另一種方式。 –

+0

@ Michael-sqlbot - 我正在使用根訪問密鑰而不是特定的IAM用戶。 – TGuimond

回答

0

非常感謝@ Michael-sqlbot爲我解決這個問題。

事實證明,當將預先簽名的URL輸出到頁面時,我強制整個URL爲小寫字母,因此AWS由於資源技術上不存在而返回了拒絕訪問錯誤。

+1

嗯,從技術上講,訪問被拒絕的錯誤是由於S3忽略了小寫的'x-amz- *'查詢字符串參數引起的,並且得出結論認爲你實際上沒有提供它應該試圖驗證的任何憑證。你可以通過將其中的一個*全部改爲全部小寫來證明這一點。 S3會突然發出一條新的錯誤信息,告訴你它缺失。將它們全部更改爲更低,並且該消息消失,因爲S3假定它是匿名請求,不提供憑證。 –