2014-01-05 3 views
2

Я пытаюсь использовать ограниченные по времени ссылки на частный контент в ведро Amazon S3 с поддержкой Cloudfront.подписанный URL-адрес для AWS Amazon Cloudfront PHP

Я хотел бы иметь возможность использовать AWS PHP API

$credentials = array("key" => $variables->strAmazonAccessKey, "secret" => $variables->strAmazonSecretKey); 
$s3 = new AmazonS3($credentials); 
$cdn = new AmazonCloudFront($credentials); 

$cdn->set_keypair_id($variables->cdn_keypair_id); 
$cdn->set_private_key($variables->cdn_private_key); 

$response = $s3->set_object_acl($bucket, $obj, AmazonS3::ACL_OWNER_FULL_CONTROL); 
return htmlspecialchars($cdn->get_private_object_url($cloudfront_id, $obj, '1 day')); 

Но я продолжаю получать это сообщение доступ запрещен

<Error> 
<Code>AccessDenied</Code> 
<Message>Access Denied</Message> 
<RequestId>BD2B4CE946ED67C4</RequestId> 
<HostId> 
JrBu9+HqhGwzRA4ILFeT2SGyp5nXEY/RrYWQDz2dzdWDIRTgVy2i3Llm460ok99M 
</HostId> 
</Error> 

cdn_private_key строка, содержащая закрытый ключ RSA, который выглядит например:

-----BEGIN RSA PRIVATE KEY----- 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlvweljbsdvljkbsadvlkjsd 
ldflsjhflasdkjfhlvbdslvahsdlviwuheliuhvlhlv= 
-----END RSA PRIVATE KEY----- 

Возможно, я что-то делаю неправильно, но я бы ожидал получить ошибку о ключе или сигнатуре вместо сообщения о запрете доступа.

Я также попытался вручную подписать, используя следующий метод, но получить ту же ошибку, только с разными НомерУзла и RequestID:

$accessId = $variables->cdn_keypair_id; 
$priv_key = $variables->cdn_private_key; 
$resource = 'https://'. $cloudfront_id .'/' . $obj; 

$expires = time() + 3600*24; 
$to_sign = '{"Statement":[{"Resource":"'.$resource.'","Condition":{"DateLessThan":{"AWS:EpochTime":'.$expires.'}}}]}';  

$signature = '*Signature will go here*'; 
$pkeyid = openssl_get_privatekey($priv_key); 
if (openssl_sign($to_sign, $signature, $pkeyid, OPENSSL_ALGO_SHA1)) { 
    $signature = urlencode(base64_encode($signature)); 
} 
return ($resource.'?Key-Pair-Id='.$accessId.'&Expires='.$expires.'&Signature='.$signature); 
+0

Это действительно указывает на очевидное, но я действительно надеюсь, что вы фактически не используете закрытый ключ, размещенный здесь. –

ответ

3

я в конечном счете решить эту проблему.

Кажется, что Amazon не очень понятна об этом ... скрытом в глубине документации AWS вам предписано установить разрешения ведра на ведро S3, чтобы позволить CloudFront получить к нему доступ.

Дальнейшая путаница возникает, когда вам необходимо установить основное свойство в политике, так как это предполагает, что вам нужно получить идентификатор пользователя Canonical. Однако это НЕ КАНАЛЬНЫЙ ИД пользователя для вашей учетной записи AWS, найденной на странице учетных данных безопасности. Вместо этого он находится в ссылке «Идентификация исходного кода» на консоли CloudFront.

Вот как это сделать ....

Сначала нужно создать/получить CloudFront Origin доступа Идентичность как это: -

$oai_id = $cdn->list_oais()->body->CloudFrontOriginAccessIdentitySummary->Id; 
if(!$oai_id) 
{ 
    $cdn->create_oai('SOME_IDENTIFIER'); 
    $oai_id = $cdn->list_oais()->body->CloudFrontOriginAccessIdentitySummary->Id; 
} 

Теперь примените политику к ковшу, чтобы CloudFront доступ: -

$cuid = $cdn->get_oai($oai_id)->body->S3CanonicalUserId; 
$policy = new CFPolicy($s3, array(
    'Statement' => array(
     array(// Statement #1 
      'Sid' => 'AddPerm', 
      'Effect' => 'Allow', 
      'Principal' => array(
       'CanonicalUser' => "$cuid" 
      ), 
      'Action' => array('s3:GetObject'), 
      'Resource' => array('arn:aws:s3:::'.$bucket.'/*') 
     ) 
    ) 
)); 
// Set the bucket policy 
$response = $s3->set_bucket_policy($bucket, $policy); 
Смежные вопросы