web-dev-qa-db-ja.com

署名済みURLを使用してAmazon s3にオブジェクトを配置するにはどうすればよいですか?

署名付きURLを使用して、s3バケットに画像をアップロードしようとしています。バケットポリシーは次のとおりです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::12345678:user/myuser",
                    "arn:aws:iam::12345678:root"
                ]
            },
        "Action": [
                "s3:List*",
                "s3:Put*",
                "s3:Get*"
            ],
            "Resource": [
                "arn:aws:s3:::myBucket",
                "arn:aws:s3:::myBucket/*"
            ]
        }
    ]
}

次のようにサーバーから署名付きURLを生成しています。

var aws = require('aws-sdk');
aws.config = {
    accessKeyId: myAccessKeyId,
    secretAccessKey: mySecretAccessKey
};

var s3 = new aws.s3();
s3.getSignedUrl('putObject', {
    Bucket: 'myBucket',
    Expires: 60*60,
    key: 'myKey'
}, function (err, url) {
    console.log(url);
});

URLを取得します。しかし、オブジェクトを配置しようとすると、次のエラーが表示されます。

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>FXXXXXXXXX</RequestId>
    <HostId>fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId>
</Error>

アップデート1

Myuserのポリシーは次のとおりです。

{
  "Version": "2012-10-17",
  "Statement": [
    {
        "Sid": "",
        "Effect": "Allow",
        "Principal": {
            "AWS": [
                "arn:aws:iam::2xxxxxxxxxxx:user/myuser",
                "arn:aws:iam::2xxxxxxxxxxx:root"
            ]
        },
        "Action": [
            "s3:*"
        ],
        "Resource": [
            "arn:aws:s3:::myBucket",
            "arn:aws:s3:::myBucket/*"
        ]
    }
  ]
}

Update 2次のオプションが設定されている場合のみアップロードできます。許可の手動選択のみが機能する場合、バケットポリシーの使用について理解できません。

Permission for everyone

アップデート3

次のコードが機能します。今、唯一の問題は署名されたURLです

 #!/bin/bash

 file="$1"

 bucket="mybucket"
 resource="/${bucket}/${file}"
 contentType="image/png"
 dateValue=`date -R`
 stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
 s3Key="AKxxxxxxxxxxxxxxxxx"
 s3Secret="/Wuxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret}     -binary | base64`
 curl -X PUT -T "${file}" \
   -H "Host: ${bucket}.s3.amazonaws.com" \
   -H "Date: ${dateValue}" \
   -H "Content-Type: ${contentType}" \
   -H "Authorization: AWS ${s3Key}:${signature}" \
   https://${bucket}.s3.amazonaws.com/${file}
20
Pravin

あなたのコードを使用してファイルをアップロードすることに成功しました。

私が従った手順は次のとおりです。

  1. 新しいバケットと新しいIAMユーザーを作成しました

  2. IAMユーザーのポリシーを以下のように設定します。

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1418647210000",
                "Effect": "Allow",
                "Action": [
                    "s3:Put*"
                ],
                "Resource": [
                    "arn:aws:s3:::myBucket/*"
                ]
            }
        ]
    }
    
  3. バケットポリシーを作成しませんでした

  4. コードを使用して、事前署名されたURLを生成しました。

    var aws = require('aws-sdk');
    aws.config = {
        accessKeyId: myAccessKeyId,
        secretAccessKey: mySecretAccessKey
    };
    
    var s3 = new aws.s3();
    s3.getSignedUrl('putObject', {
        Bucket: 'myBucket',
        Expires: 60*60,
        Key: 'myKey'
    }, function (err, url) {
        console.log(url);
    });
    
  5. 以下のように、画面上のURLをコピーし、curlを使用してアップロードをテストしました。

    curl.exe -k -X PUT -T "someFile" "https://myBucket.s3.amazonaws.com/myKey?AWSAccessKeyId=ACCESS_KEY_ID&Expires=1457632663&Signature=Dhgp40j84yfjBS5v5qSNE4Q6l6U%3D"
    

私の場合、ポリシーの変更が有効になるまでに通常5〜10秒かかりました。そのため、最初に失敗した場合は、しばらく送信し続けるようにしてください。

お役に立てれば。

14
Volkan Paksoy
  1. IAMコンソールで、 ユーザーをクリック
  2. 右側のリストで、使用したIAMユーザーを選択します(「myuser」でなければなりません)
  3. サブタブで権限を選択します
  4. [Attach Policy]をクリックして、[AmazonS3FullAccess]を選択します

最終ページは this のようになります。

また、Security Credentialsサブタブをチェックすることもできます。accessKeyIdがリストに含まれている必要があります。 secretAccessKeyは再び取得できません。

3
Hank Chiu

ユーザーからのアクセスを許可するために、バケットに権限を正しく設定しました。

ただし、ユーザーがS3サービスにアクセスできるようにするには、ユーザーのポリシーを編集する必要もあります。

認証情報を使用して自己署名URLを生成するユーザーのIAMポリシーを編集します。このようなものがすべてを確実にカバーします。

{
  "Statement": [
    {
      "Sid": "AllowAllS3Access",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
1
Rory

あなたにも役立つかもしれません:) ContentTypeプロパティを追加してください:

s3.getSignedUrl('putObject', {
    Bucket: 'myBucket',
    Expires: 60*60,
    Key: 'myKey',
    ContentType: 'image/jpeg',
}, function (err, url) {
   console.log(url);
});
1
Hugo Mallet