署名付き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次のオプションが設定されている場合のみアップロードできます。許可の手動選択のみが機能する場合、バケットポリシーの使用について理解できません。
アップデート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}
あなたのコードを使用してファイルをアップロードすることに成功しました。
私が従った手順は次のとおりです。
新しいバケットと新しいIAMユーザーを作成しました
IAMユーザーのポリシーを以下のように設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1418647210000",
"Effect": "Allow",
"Action": [
"s3:Put*"
],
"Resource": [
"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をコピーし、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秒かかりました。そのため、最初に失敗した場合は、しばらく送信し続けるようにしてください。
お役に立てれば。
ユーザーからのアクセスを許可するために、バケットに権限を正しく設定しました。
ただし、ユーザーがS3サービスにアクセスできるようにするには、ユーザーのポリシーを編集する必要もあります。
認証情報を使用して自己署名URLを生成するユーザーのIAMポリシーを編集します。このようなものがすべてを確実にカバーします。
{
"Statement": [
{
"Sid": "AllowAllS3Access",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "*"
}
]
}
あなたにも役立つかもしれません:) ContentTypeプロパティを追加してください:
s3.getSignedUrl('putObject', {
Bucket: 'myBucket',
Expires: 60*60,
Key: 'myKey',
ContentType: 'image/jpeg',
}, function (err, url) {
console.log(url);
});