简体   繁体   中英

Amazon CloudFront and S3

I am new to Amazon AWS and am trying to setup a system to upload images for users. After setting up everything, I am unable to validate a token. Below, I will explain all of the configuration I have done.

I created an S3 bucket and I configured the CORS for that bucket:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Next, I setup a CloudFront distribution that points to this S3 bucket. It is set to allow all HTTP methods (which includes "PUT"). An origin access identity is also created so that images are only viewable by the CloudFront url, instead of S3.

I then created an IAM user and have created a policy for that user so that I can request temporary credentials when I need to upload an image via CloudFront:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1504225496000",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

For now, I set the permissions to full access just for development. Eventually I will add more tighter permissions.

Once this is complete, I then request temporary credentials from an API like so:

var securityClient =
                new AmazonSecurityTokenServiceClient(Variables.AWSUserWriteId, Variables.AWSUserWriteKey);

            var request = new GetSessionTokenRequest
            {
                DurationSeconds = 900
            };

            var tempCredentials = await securityClient.GetSessionTokenAsync(request);
            return new ApiResponse(Enums.ResponseStatus.Success, new JObject
            {
                {"id", tempCredentials.Credentials.AccessKeyId},
                {"key", tempCredentials.Credentials.SecretAccessKey},
                {"token", tempCredentials.Credentials.SessionToken}
            }, null);

This is returned to the browser client (note, I am able to successfully get the three values).

Using these values, I use the AWS-SDK to call the upload process:

let id = response.data.JsonData.id;
        let key = response.data.JsonData.key;
        let token = response.data.JsonData.token;

        let s3 = new AWS.S3({
            accessKeyId: id,
            secretAccessKey: key,
            sessionToken: token,
            endpoint: cloudFrontUrl //https://d3goqf5vihdmh2.cloudfront.net
        });
        s3.upload({Body: file, Bucket: amazonS3BucketName, Key: file.name}, (err, data) => {
            console.log(err);
            console.log(data);
            let hello = "hello";
        }).on("httpUploadProgress", evt => {
            console.log(evt);
        });

However, after doing all this, an error is returned:

"The provided token is malformed or otherwise invalid."

The user has full permissions, and as far as I can tell, I should have everything setup correctly, unless I am missing something? I cannot find a solution anywhere after a search on google and documentation, I am completely stuck here.

EDIT: Here is more information of the requests actually going out. These are the request headers as provided by Google Browser Dev Tools:

:authority:d3goqf5vihdmh2.cloudfront.net
:method:PUT
:path:/**removingforprivacy**.development/**removingforprivacy**.png
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-US,en;q=0.8
authorization:AWS4-HMAC-SHA256 Credential=**removingforprivacy**/20170901/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-
amz-security-token;x-amz-user-agent, 
Signature=180d55d69eb0577b77d14b8938c675cbd8798924132c7367d02fbd59b5e8a3d3
content-length:33041
content-type:application/octet-stream
origin:http://localhost:3000
referer:http://localhost:3000/postnew
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20170901T024531Z
x-amz-security-token:FQoDYXdzEMz//////////wEaDDJE64k3fztWLnZWJiKrAbIUNroRDzBfHcFJrPTUIgNSKFWdZDM4Nt0a7UCxwnWopLRDJAMiwt/gX1svqe5ZJsUL+yHTubJylLVvIIZdxsGGCeSZhmaquyd5jWsx9n+PeHB5MFbxkcDdRWhaQ8eXobABH0Q53xxH/zBXxIZTn/qEERgHPjfaPVLLmzQmbd6+toc/WQX5y3HZMvf7ZgTh3KdoHWDwJEmCeYx6NuyNpR9NIiubVvI/2gH8zijGk6PNBQ==
x-amz-user-agent:aws-sdk-js/2.107.0 callback

Looks like you need to use the SQS Queue Service in order to hand out temporary security credentials. See the following here Using Temporary Security Credentials

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM