AWS S3 Post Object Rejects Extra Form Fields

╄→гoц情女王★ 提交于 2021-01-01 09:25:05

问题


I'm trying to set the storage class of an uploaded image to an AWS S3 bucket. I have it working except for adding the storage class to the request. The S3 Post Object Documentation states there can be a form input field named "x-amz-storage-class" but adding it, or any other field, throws an AWS error indicating that there are too many input fields for the post. I tried adding it to the object policy but that causes an Policy error: "Policy Condition failed: [“eq”, “$x-amz-storage-class”, “ONEZONE_IA”]". I'm using JSP and the form's input fields are shown below. Any help would be appreciated.

<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 ****

Errors:

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>

回答1:


I have this working now. The policy has fields that must match the fields on the form. "x-amz-storage-class" has to be added to both the form fields and policy. My guess is the encoded policy is signed for security reasons which makes it secure and the form fields must match the policy fields to ensure they weren't changed. Why both are needed is beyond me. Corrected code is below:

<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;
}

For completeness and because its not obvious, the storage class values are:

Default: STANDARD

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

Here is the AWS S3 Post Object documentation



来源:https://stackoverflow.com/questions/64975612/aws-s3-post-object-rejects-extra-form-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!