【问题标题】:Amazon CloudFront and S3亚马逊 CloudFront 和 S3
【发布时间】:2018-02-10 01:49:27
【问题描述】:

我是 Amazon AWS 的新手,我正在尝试设置一个系统来为用户上传图像。设置完所有内容后,我无法验证令牌。下面,我将解释我所做的所有配置。

我创建了一个 S3 存储桶并为该存储桶配置了 CORS:

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

接下来,我设置了指向此 S3 存储桶的 CloudFront 分配。它设置为允许所有 HTTP 方法(包括“PUT”)。还会创建一个源访问身份,以便只能通过 CloudFront url 而非 S3 查看图像。

然后,我创建了一个 IAM 用户并为该用户创建了一个策略,以便在需要通过 CloudFront 上传图像时请求临时凭证:

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

目前,我将权限设置为完全访问权限,仅用于开发。最终我会添加更严格的权限。

完成后,我会像这样从 API 请求临时凭据:

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

这是返回给浏览器客户端(注意,我能够成功获取这三个值)。

使用这些值,我使用 AWS-SDK 调用上传过程:

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

但是,做完这一切之后,返回一个错误:

"The provided token is malformed or otherwise invalid."

用户拥有完全权限,据我所知,我应该正确设置所有内容,除非我遗漏了什么?在谷歌和文档上搜索后,我无法在任何地方找到解决方案,我完全被困在这里。

编辑:这是实际发出的请求的更多信息。这些是 Google 浏览器开发工具提供的请求标头:

: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

【问题讨论】:

  • endpoint: cloudFrontUrl 无效,在这里...您混合了两个不同的概念。要授权通过 CloudFront 发送的请求,您需要使用不同算法的 CloudFront 签名 URL。这反过来又是有问题的,因为根据存储桶策略,CloudFront URL 对于源访问身份可以执行的任何方法都是有效的。
  • 感谢您的信息。建议的方法是什么?我真的不需要保护获取操作,但是对于添加和删除,我想保护这一点,我想通过 CloudFront 进行所有操作。我想我可以直接在 S3 上进行添加和删除,然后在 CloudFront 上并接受用户可以通过 S3 和 CloudFront URL 访问对象的事实,除非有办法实现我想要的做什么?
  • 我正在对一些可用选项进行完整的解释。您能否阐明为什么要通过 CloudFront 进行所有操作?这种方法没有任何问题,并且有一些优势,但有些人认为通过 CloudFront 上传会与缓存交互,但事实并非如此。此外,您的价格等级选择以及存储桶和用户的位置可能会使 S3 Transfer Acceleration 成为上传的更好选择。它与通过 CloudFront 上传的技术完全相同(它使用 CloudFront 网络),但可能是一种更有利的定价模型。你的想法?
  • 看起来我完全掩盖了关于传输加速的那篇文章。谢谢你的信息。这是否意味着我可以像直接上传到 S3 一样使用 JavaScript sdk 启用传输加速的临时凭证?我假设我不必面对与 CloudFront 相同的困境,但只是想确认一下。我还假设我可以将 CloudFront 用于获取请求,并为放置和删除请求启用传输加速?
  • 正确。传输加速有一个“陷阱”——不要在存储桶名称中使用任何点。 Transfer Acceleration 启用了两个新端点,example-bucket.s3-accelerate.amazonaws.comexample-bucker.s3-accelerate.dualstack.amazonaws.com。签名 URL 使用与标准 S3 签名 URL 相同的算法。

标签: amazon-web-services amazon-s3 aws-sdk amazon-cloudfront


【解决方案1】:

看起来您需要使用 SQS 队列服务来分发临时安全凭证。请参阅以下内容 Temporary Security Credentials

【讨论】:

猜你喜欢
  • 2014-09-13
  • 2012-05-01
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
相关资源
最近更新 更多