2013-09-19 4 views
9

Это продолжение моего previous question относительно подписания документа политики с использованием профилей экземпляров.Загрузка браузера на s3 с ролями экземпляра

Я разрабатываю систему, которая позволяет перетаскивать &. Загружает файлы непосредственно в ведро S3; сначала выполняется запрос AJAX на мой сервер, содержащий метаданные файла. После проверки мой сервер отвечает параметрами формы, которые используются для завершения загрузки.

Процесс настройки загрузки на основе браузера хорошо объяснен here, и все это работает в локальной тестовой среде.

Однако после того, как мое приложение развертывается на экземпляре EC2, я вижу эту ошибку, когда браузер пытается загрузить файл:

<Error> 
    <Code>InvalidAccessKeyId</Code> 
    <Message>The AWS Access Key Id you provided does not exist in our records.</Message> 
    <RequestId>...</RequestId> 
    <HostId>...</HostId> 
    <AWSAccessKeyId>ASIAxxxyyyzzz</AWSAccessKeyId> 
</Error> 

Значение ASIAxxxyyyzzz здесь идет от учетных ролей экземпляра, полученный из службы метаданных; кажется, что эти учетные данные не могут использоваться вне EC2 для облегчения загрузки на основе браузера.

Я смотрел на Security Token Service, а также для создания другого набора временных полномочий, делая это:

$token = $sts->assumeRole(array(
    'RoleArn' => 'arn:aws:iam::xyz:role/mydomain.com', 
    'RoleSessionName' => 'uploader', 
)); 

$credentials = new Credentials($token['Credentials']['AccessKeyId'], $token['Credentials']['SecretAccessKey']); 

Вызов Гивенс мне новый набор учетных данных, но он дает ту же ошибку, как указано выше, если Я использую это.

Я надеюсь, что кто-то сделал это раньше, и может сказать мне, что глупо я пропустил :)

ответ

3

Как указано dcro's answer, токен сеанса должен быть передан службе, используемой при использовании временных учетных данных. official documentation упоминает поле x-amz-security-token, но, похоже, он предназначен только для DevPay; это, вероятно, потому, что DevPay использует один и тот же тип временных учетных данных и поэтому требует токена безопасности сеанса.

2013-10-16: Amazon обновил свою документацию, чтобы сделать это более очевидным.

Как выяснилось, даже не требуется использовать STS; учетные данные, полученные службой метаданных, также имеют такой токен сеанса.Этот токен автоматически передается для вас, когда SDK используется вместе с временными учетными данными, но в этом случае окончательный запрос выполняется браузером и, следовательно, должен быть явно передан.

Ниже мой рабочий код:

$credentials = Credentials::factory(); 
$signer = new S3Signature(); 
$policy = new AwsUploadPolicy(new DateTime('+1 hour', new DateTimeZone('UTC'))); 

$policy->setBucket('upload.mydomain.com'); 
$policy->setACL($policy::ACL_PUBLIC_READ); 
$policy->setKey('uploads/test.jpg'); 
$policy->setContentType('image/jpeg'); 
$policy->setContentLength(5034); 

$fields = array(
    'AWSAccessKeyId' => $credentials->getAccessKeyId(), 
    'key' => $path, 
    'Content-Type' => $type, 
    'acl' => $policy::ACL_PUBLIC_READ, 
    'policy' => $policy, 
); 

if ($credentials->getSecurityToken()) { 
    // pass security token 
    $fields['x-amz-security-token'] = $credentials->getSecurityToken(); 
    $policy->setSecurityToken($credentials->getSecurityToken()); 
} 

$fields['signature'] = $signer->signString($policy, $credentials); 

Я использую вспомогательный класс для построения политики, называется AwsUploadPolicy; на момент написания это не является полным, но это может помочь другим с аналогичной проблемой.

Разрешения были последней проблемой; мой код устанавливает ACL на public-read, и для этого требуется дополнительное разрешение s3:PutObjectAcl.

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Action": [ 
     "s3:PutObject", 
     "s3:PutObjectAcl" 
     ], 
     "Sid": "Stmt1379546195000", 
     "Resource": [ 
     "arn:aws:s3:::upload.mydomain.com/uploads/*" 
     ], 
     "Effect": "Allow" 
    } 
    ] 
} 
+0

hi jack, можете ли вы, пожалуйста, опубликовать свою работу по загрузке на s3 с использованием только временных учетных данных. Мне сложно понять это. T__T –

+0

@WonderingCoder Загрузка сама по себе не происходит в PHP; это делается в JavaScript и использует класс 'FormData' (для браузеров, которые его поддерживают) и CORS. Это та часть, о которой вы хотели бы узнать больше? –

+0

привет благодарю вас за ответ. Пожалуйста, посмотрите мой пост, я тоже использую временные учетные данные. Единственное наше отличие в том, что вы использовали SDK: [мой пост] (http://stackoverflow.com/questions/19401936/signaturedoesnotmatch-browser-based-upload -в-s3). Это было 4 дня, и я все еще пытаюсь сделать эту работу –

6

Документах AWS очень запутанным об этом, но я подозреваю, что вам нужно включить параметр x-amz-security-token в запросе POST для загрузки S3 и что его значение соответствует SessionToken, которое вы получаете от STS ($token['Credentials']['SessionToken']).

Временные учетные данные STS действительны только при включении соответствующего токена безопасности.

В AWS documentation for the POST request говорится, что:

Каждого запрос, который использует Amazon DevPay требует два х-АМЗА-безопасность-маркер поля формы: один для продукта маркеров и один для маркеров пользователя.

, но этот параметр также используется за пределами DevPay, чтобы передать токен STS, и вам нужно будет передать его один раз в поля формы.

+0

Хорошо, это кажется разумным. Позволь мне пожарить это сегодня вечером и посмотреть, как это происходит :) –

+0

Я немного поближе с этим; он больше не жалуется на неизвестный идентификатор доступа, но теперь он дает ошибку «access denied» :( –

+0

Hm .. попробуйте дать ему разрешение 's3: PutObjectAcl' в IAM и посмотрим, поможет ли он. – dcro

Смежные вопросы