9

これは、インスタンス プロファイルを使用したポリシー ドキュメントの署名に関する以前の質問の補足です。

S3 バケットにドラッグ アンド ドロップで直接アップロードできるシステムを開発しています。AJAX 要求は、最初にファイル メタデータを含むサーバーに対して行われます。検証が完了すると、サーバーはアップロードを完了するために使用されるフォーム パラメータで応答します。

ブラウザ ベースのアップロードをセットアップするプロセスは、こちらで詳しく説明されており、ローカルのテスト環境ではすべて期待どおりに動作します。

ただし、アプリケーションが 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インスタンス ロールの credentialsから取得されます。ブラウザベースのアップロードを容易にするために、これらの資格情報を 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']);

この呼び出しにより、新しい資格情報のセットが提供されましたが、それを使用すると上記と同じエラーが発生します。

誰かがこれを以前にやったことがあり、私が見逃したばかげたことを教えてくれることを願っています:)

4

2 に答える 2

3

dcro's answerで指摘されているように、一時的な資格情報を使用する場合は、使用しているサービスにセッション トークンを渡す必要があります。公式ドキュメントにはこのフィールドについて言及されてい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"
    }
  ]
}
于 2013-10-01T00:06:00.973 に答える