How do I upload using AWS S3 PRESIGNED URL as HTML?

Viewed 1420

Currently, S3 PRESIGNED URL is being obtained through SPRING BOOT.

I want to upload an image from FRONT by passing the URL in HTML.

However, the CODE you have written now receives SignatureDoesNotMatch.

MY SERVER CODE

public String getSignedURL(String fileName){
    ZonedDateTime uploadTime=ZonedDateTime.now(ZoneId.of("Asia/Seoul"));

    Date expiration=new Date();
    long expTimeMillis =expiration.getTime();
    expTimeMillis+=1000*60*1; //1Min
    expiration.setTime(expTimeMillis);

    //+uploadTime.format(DateTimeFormatter.ofPattern("yy.mm.dd HH:mm:ss z"))

    String objectKey="boardimages/"+fileName;
    URL urls=null;
    try {
        GeneratePresignedUrlRequest url = new GeneratePresignedUrlRequest(bucketName, objectKey)
                .withMethod(HttpMethod.POST)
                .withExpiration(expiration);

        url.addRequestParameter(Headers.S3_CANNED_ACL, CannedAccessControlList.PublicRead.toString());
        urls = s3Client.generatePresignedUrl(url);
    }catch(Exception e){
        e.printStackTrace();
    }

    System.out.println("pre-signed url : "+urls);
    return urls.toString();
}

My controller

@RequestMapping(value="/upload",method = RequestMethod.POST)
public String uploadFile(Model model,HttpServletRequest request){
    Map<String,String[]> emp=request.getParameterMap();

    String fileName=emp.get("file")[0];
    System.out.println("uploading file Name = "+fileName);

    String persgined=awsService.getSignedURL(fileName);
    model.addAttribute("fileName","boardimages/"+fileName); //object key -> .jpg   boardimage->s3 bucket dir
    model.addAttribute("url",persgined);
    model.addAttribute("accesskey",awsService.getAccessKey());
    return "galleryUrlUpload";
}

my html form code

<form role="form" action="#" th:action="${url}" method="post" enctype="multipart/form-data">
    <!--<input type="hidden" name="_method" value="PUT"/>-->
<input type="hidden" name="key" value="${fileName}"/>
<input type="hidden" name="AWSAccessKeyId" value="${accesskey}" />
<input type="file" name="file">
<input type="submit" value="click"></input>

My Error

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<AWSAccessKeyId>---</AWSAccessKeyId>
<StringToSign>
AWS4-HMAC-SHA256 20210310T081246Z 20210310/ap-northeast-2/s3/aws4_request 38d7447c7cb20368bb9a690afc14029b6983a423b7400f214d4acb119ab181b6
</StringToSign>
<SignatureProvided>
fe2cb0da2a770b64014d971c270731d70788519447f64f63dfc9cd881d0c23c1
</SignatureProvided>
<StringToSignBytes>
41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 31 30 33 31 30 54 30 38 31 32 34 36 5a 0a 32 30 32 31 30 33 31 30 2f 61 70 2d 6e 6f 72 74 68 65 61 73 74 2d 32 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 33 38 64 37 34 34 37 63 37 63 62 32 30 33 36 38 62 62 39 61 36 39 30 61 66 63 31 34 30 32 39 62 36 39 38 33 61 34 32 33 62 37 34 30 30 66 32 31 34 64 34 61 63 62 31 31 39 61 62 31 38 31 62 36
</StringToSignBytes>
<CanonicalRequest>
POST /boardimages/1540.jpg X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAV4JZWYET2PT6UO6G%2F20210310%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Date=20210310T081246Z&X-Amz-Expires=59&X-Amz-SignedHeaders=host&x-amz-acl=public-read host:infostarbinary.s3.ap-northeast-2.amazonaws.com host UNSIGNED-PAYLOAD
</CanonicalRequest>
<CanonicalRequestBytes>
50 4f 53 54 0a 2f 62 6f 61 72 64 69 6d 61 67 65 73 2f 31 35 34 30 2e 6a 70 67 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 56 34 4a 5a 57 59 45 54 32 50 54 36 55 4f 36 47 25 32 46 32 30 32 31 30 33 31 30 25 32 46 61 70 2d 6e 6f 72 74 68 65 61 73 74 2d 32 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 31 30 33 31 30 54 30 38 31 32 34 36 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 35 39 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 68 6f 73 74 26 78 2d 61 6d 7a 2d 61 63 6c 3d 70 75 62 6c 69 63 2d 72 65 61 64 0a 68 6f 73 74 3a 69 6e 66 6f 73 74 61 72 62 69 6e 61 72 79 2e 73 33 2e 61 70 2d 6e 6f 72 74 68 65 61 73 74 2d 32 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44
</CanonicalRequestBytes>
<RequestId>RG1VPG1549WMPKZ9</RequestId>
<HostId>
XMnFDE1xzfvkwsLsJPVuxUEbLRlH5muADarR/p5KCTp3U9N0f6uI1CR8WL+rWTPbI0V4kZ7LpzA=
</HostId>
</Error>

I referenced here https://boto3.amazonaws.com/v1/documentation/api/1.11.4/guide/s3-presigned-urls.html but didn't understand the policy and signature of the last html.

What do I need to pass as policy and signature in order to work? Or please tell me to upload s3 via presigned url using html.

1 Answers

If you are using Java to perform this use case, please refer to the Java documentation as opposed to Python. See:

Working with Amazon S3 Presigned URLs

The logic to upload content via a presigned URL using the AWS SDK for Java V2 can be found in that topic.

If you are not familiar with using Java V2, please refer to this quick start.

UPDATE: If you want to upload content from a web page (as your comment suggests), then you should use the AWS SDK for Javascript - not the Java API. Here is the example to refer to:

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/s3-example-creating-buckets.html#s3-create-presigendurl-put

Related