J'essaie d'utiliser une URL signée pour télécharger des images dans le compartiment s3. Voici la politique de mon seau:
{
"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/*"
]
}
]
}
Je génère l'URL signée à partir du serveur comme suit:
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);
});
Je reçois l'URL. Mais quand j'essaye de mettre un objet, j'obtiens l'erreur suivante:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>FXXXXXXXXX</RequestId>
<HostId>fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId>
</Error>
Mise à jour 1
Voici la politique de 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 Je peux télécharger uniquement lorsque l'option suivante est définie. Je ne comprends pas ce qui est l'utilisation de la politique de compartiment si seulement la sélection manuelle de permission fonctionne.
Mise à jour 3
Le code suivant fonctionne. Maintenant, le seul problème est l'URL signée
#!/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}
J'ai réussi à télécharger un fichier avec succès en utilisant votre code.
Voici les étapes que j'ai suivies:
Création d'un nouveau compartiment et d'un nouvel utilisateur IAM
Définissez la stratégie de l'utilisateur IAM comme suit:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1418647210000",
"Effect": "Allow",
"Action": [
"s3:Put*"
],
"Resource": [
"arn:aws:s3:::myBucket/*"
]
}
]
}
N'a PAS créé de politique de compartiment
Utilisez votre code pour générer l'URL pré-signée:
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);
});
Copiez l'URL à l'écran et utilisez curl pour tester le téléchargement comme ci-dessous:
curl.exe -k -X PUT -T "someFile" "https://myBucket.s3.amazonaws.com/myKey?AWSAccessKeyId=ACCESS_KEY_ID&Expires=1457632663&Signature=Dhgp40j84yfjBS5v5qSNE4Q6l6U%3D"
Dans mon cas, il a fallu généralement 5 à 10 secondes pour que les modifications apportées à la stratégie prennent effet. Si cela échoue la première fois, assurez-vous de continuer à l'envoyer pendant un moment.
J'espère que cela t'aides.
Vous avez correctement configuré les autorisations sur le compartiment, afin de permettre l'accès de l'utilisateur.
Mais vous devez également modifier la stratégie de l'utilisateur pour lui permettre d'accéder au service S3.
Modifiez la stratégie IAM de l'utilisateur dont vous utilisez les informations d'identification pour générer l'URL auto-signée. Quelque chose comme ça couvrira définitivement tout:
{
"Statement": [
{
"Sid": "AllowAllS3Access",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "*"
}
]
}
La dernière page sera comme ceci .
Vous pouvez également consulter le sous-onglet Informations d'identification de sécurité, votre accessKeyId devrait figurer dans la liste. Le secretAccessKey ne peut tout simplement pas se reproduire.
Cela peut aussi vous aider:) Ajoutez un ContentType property:
s3.getSignedUrl('putObject', {
Bucket: 'myBucket',
Expires: 60*60,
Key: 'myKey',
ContentType: 'image/jpeg',
}, function (err, url) {
console.log(url);
});