Comment rendre tous les objets du compartiment AWS S3 publics par défaut?

151

J'utilise une bibliothèque PHP pour télécharger un fichier dans mon bucket. J'ai mis l'ACL sur public-read-write et cela fonctionne bien mais le fichier est toujours privé.

J'ai constaté que si je change le bénéficiaire en Tout le monde , le fichier devient public. Ce que je veux savoir, c'est comment faire pour que le bénéficiaire par défaut de tous les objets de mon compartiment soit défini sur «Tout le monde» . Ou existe-t-il une autre solution pour rendre les fichiers publics par défaut?

Le code que j'utilise est ci-dessous:

public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
    if ($input === false) return false;
    $rest = new S3Request('PUT', $bucket, $uri);

    if (is_string($input)) $input = array(
        'data' => $input, 'size' => strlen($input),
        'md5sum' => base64_encode(md5($input, true))
    );

    // Data
    if (isset($input['fp']))
        $rest->fp =& $input['fp'];
    elseif (isset($input['file']))
        $rest->fp = @fopen($input['file'], 'rb');
    elseif (isset($input['data']))
        $rest->data = $input['data'];

    // Content-Length (required)
    if (isset($input['size']) && $input['size'] >= 0)
        $rest->size = $input['size'];
    else {
        if (isset($input['file']))
            $rest->size = filesize($input['file']);
        elseif (isset($input['data']))
            $rest->size = strlen($input['data']);
    }

    // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
    if (is_array($requestHeaders))
        foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
    elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
        $input['type'] = $requestHeaders;

    // Content-Type
    if (!isset($input['type'])) {
        if (isset($requestHeaders['Content-Type']))
            $input['type'] =& $requestHeaders['Content-Type'];
        elseif (isset($input['file']))
            $input['type'] = self::__getMimeType($input['file']);
        else
            $input['type'] = 'application/octet-stream';
    }

    // We need to post with Content-Length and Content-Type, MD5 is optional
    if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
        $rest->setHeader('Content-Type', $input['type']);
        if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);

        $rest->setAmzHeader('x-amz-acl', $acl);
        foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
        $rest->getResponse();
    } else
        $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');

    if ($rest->response->error === false && $rest->response->code !== 200)
        $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
    if ($rest->response->error !== false) {
        trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
        return false;
    }
    return true;
}
condo1234
la source

Réponses:

300

Allez à http://awspolicygen.s3.amazonaws.com/policygen.html Remplissez les détails tels que: entrez la description de l'image ici Dans Action, sélectionnez "GetObject" Sélectionnez "Ajouter une déclaration" Puis sélectionnez "Générer une stratégie"

Copiez l'exemple de texte:

{
  "Id": "Policy1397632521960",
  "Statement": [
    {
      "Sid": "Stmt1397633323327",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucketnm/*",
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

Accédez maintenant à votre console AWS S3, au niveau du compartiment, cliquez sur Propriétés, Développer les autorisations, puis sélectionnez Ajouter une stratégie de compartiment. Collez le code généré ci-dessus dans l'éditeur et appuyez sur Enregistrer.

Tous vos éléments du bucket seront publics par défaut.

jaxxbo
la source
8
C'est la bonne réponse. Contrairement à la réponse précédente, cet article m'a également appris comment créer des politiques et ce qu'elles font. Après avoir lu ceci, je peux écrire une politique manuellement.
Jason Cheladyn
2
J'ai voté pour cette réponse pour la même raison que @liyicky, les instructions détaillées étaient une belle introduction au lieu de simplement recevoir la réponse.
brendo
Pareil ici. AWS a tendance à être parfois opaque et probablement pour une très bonne raison. Cette forme de réponse est utile à partir de zéro.
Jerome
Cela fonctionne lorsque vous ajoutez de nouveaux fichiers au bucket, mais que je dois modifier les fichiers qui existent déjà dans le bucket pour qu'ils soient publics.
Radenko Zec le
137

Si vous souhaitez rendre tous les objets publics par défaut, le moyen le plus simple est de le faire via une stratégie de compartiment au lieu de listes de contrôle d'accès (ACL) définies sur chaque objet individuel.

entrez la description de l'image ici

Vous pouvez utiliser AWS Policy Generator pour générer une stratégie de compartiment pour votre compartiment.

Par exemple, la stratégie suivante permettra à quiconque de lire chaque objet de votre compartiment S3 (remplacez-le simplement <bucket-name>par le nom de votre compartiment):

{
  "Id": "Policy1380877762691",
  "Statement": [
    {
      "Sid": "Stmt1380877761162",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<bucket-name>/*",
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

La stratégie de compartiment contient une liste de Statementset chaque instruction a un Effect(ou Allowou Deny) pour une liste de ceux Actionsqui sont exécutés par Principal(l'utilisateur) sur le spécifié Resource(identifié par un Amazon Resource Nameou ARN).

Le Idest juste un identifiant de stratégie facultatif et le Sidest un identifiant d'instruction unique facultatif.

Pour les stratégies de compartiment S3, les ARN de ressources prennent la forme:

arn:aws:s3:::<bucket_name>/<key_name>

L'exemple ci-dessus permet à ( ) any Effect: Allow( Principal: *) d'accéder ( Action: s3:GetObject) à n'importe quel objet du bucket ( Resource: arn:aws:s3:::<bucket-name>/*).

dcro
la source
N'y a-t-il pas un moyen avec le panneau de contrôle?
ianaz
2
@ianaz Vous pouvez ajouter cette stratégie de compartiment à un compartiment via la console AWS (panneau de configuration)
dcro
@ianaz voir ma réponse ci-dessous.
jaxxbo
Notez également qu'il y a un lien «exemples de politiques» dans le lien ci-dessus qui donne les informations exactes nécessaires pour couper et coller dans le générateur de politiques. À mesure que aws met à jour les API, il est plus probable que cela reste correct. A travaillé comme un charme pour moi ce matin.
keithpjolley
Principal: *m'a beaucoup aidé. Merci!
iedmrc le
2

Mon problème était légèrement différent, mais comme cette question est en haut de la recherche Google, je laisse ma solution, peut-être qu'elle aidera quelqu'un.

J'avais déjà eu un accès complet au compartiment S3 auparavant, mais un jour, il a juste commencé à revenir Access Deniedà tous mes fichiers. La solution était simple et directe.

  1. Aller à Services-S3
  2. Cliquez sur votre compartiment S3
  3. Passer à l' Permissionsonglet, puis aller à l' Bucket Policyonglet
  4. Et cliquez sur le Savebouton.

Il devrait réaffecter l'autorisation sur tous vos fichiers.

entrez la description de l'image ici

Quoi qu'il en soit, voici plein bucket policyqui permet de rendre tous les objets publics

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPublicRead",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::enter-here-your-media-bucket-name/*"
        }
    ]
}
Serhii Popov
la source