L'objet de publication AWS S3 rejette les champs de formulaire supplémentaires

Nov 24 2020

J'essaie de définir la classe de stockage d'une image téléchargée dans un compartiment AWS S3. Je le fais fonctionner sauf pour ajouter la classe de stockage à la demande. La documentation de l'objet de publication S3 indique qu'il peut y avoir un champ d'entrée de formulaire nommé «x-amz-storage-class», mais l'ajout de celui-ci, ou de tout autre champ, génère une erreur AWS indiquant qu'il y a trop de champs d'entrée pour la publication. J'ai essayé de l'ajouter à la politique d'objet mais cela provoque une erreur de politique: "La condition de politique a échoué: [" eq "," $ x-amz-storage-class "," ONEZONE_IA "]". J'utilise JSP et les champs de saisie du formulaire sont indiqués ci-dessous. Toute aide serait appréciée.

<input type="hidden" name="key" value="<%= imageFileName %>">
<input type="hidden" name="AWSAccessKeyId" value="<%= S3AccessKeyId %>"> 
<input type="hidden" name="acl" value="private"> 
<input type="hidden" name="success_action_redirect" value="<%= s3SuccessAction %>">
<input type="hidden" name="policy" value="<%= encPolicy %>" >
<input type="hidden" name="signature" value="<%= signature %>" >
<input type="hidden" name="Content-Type" value="image/jpeg">
<input type="hidden" name="x-amz-storage-class" value="ONEZONE_IA">   ***** CAUSES ERROR ****

Les erreurs:

Invalid according to Policy: Policy Condition failed: [“eq”, “$x-amz-storage-class”, “STANDARD_IA”]

<Error>
<Code>AccessDenied</Code>
<Message>
Invalid according to Policy: Extra input fields: x-amz-storage-class
</Message>
<RequestId>1104FC046523752C</RequestId>
<HostId>
m0xPpMKJqBG6kZsdQfl/RY92dHprnvtGtrijHLqVtieM51ew+Mkp0mXGbTwKM7OsoUq6ZZUVIc0=
</HostId>
</Error>

Réponses

glez Nov 24 2020 at 05:56

J'ai cela fonctionne maintenant. La stratégie comporte des champs qui doivent correspondre aux champs du formulaire. "x-amz-storage-class" doit être ajouté à la fois aux champs du formulaire et à la stratégie. Je suppose que la politique codée est signée pour des raisons de sécurité, ce qui la rend sécurisée et les champs du formulaire doivent correspondre aux champs de la politique pour s'assurer qu'ils n'ont pas été modifiés. Pourquoi les deux sont nécessaires me dépasse. Le code corrigé est ci-dessous:

<fieldset>

    <input type="hidden" name="key" value="<%= imageFileName %>">
    <input type="hidden" name="AWSAccessKeyId" value="<%= S3AccessKeyId %>"> 
    <input type="hidden" name="acl" value="private"> 
    <input type="hidden" name="success_action_redirect" value="<%= s3SuccessAction %>">
    <input type="hidden" name="policy" value="<%= encPolicy %>" >
    <input type="hidden" name="signature" value="<%= signature %>" >
    <input type="hidden" name="Content-Type" value="image/jpeg">
    <input type="hidden" name="x-amz-storage-class" value="ONEZONE_IA">
    

public static String encodeS3Policy(String s3SuccessAction, String bucket) throws Exception
{
    String policy =
        "{\"expiration\": \"2040-01-01T00:00:00Z\"," +
          "\"conditions\": [" +
            "{\"bucket\": \"" + bucket + "\"}," +
            "[\"starts-with\", \"$key\", \"\"]," + "{\"acl\": \"private\"}," + "{\"success_action_redirect\": \"" + s3SuccessAction + "\"}," + "[\"starts-with\", \"$Content-Type\", \"\"]," +
            "{\"x-amz-storage-class\": \"ONEZONE_IA\"}," +
            "[\"content-length-range\", 0, 10485760]" +                                 // 10 MB max file up load
            "]" +
        "}";

    policy.replaceAll("\n","").replaceAll("\r","");


    // Encode the policy
    String encPolicy = Base64.getEncoder().encodeToString(policy.getBytes("UTF-8"));

    return encPolicy;
}

Par souci d'exhaustivité et parce que ce n'est pas évident, les valeurs de la classe de stockage sont:

Default: STANDARD

STANDARD | REDUCED_REDUNDANCY | GLACIER | STANDARD_IA | ONEZONE_IA | INTELLIGENT_TIERING | DEEP_ARCHIVE 

Voici la documentation AWS S3 Post Object