Lambda /预先签名的URL访问被拒绝

时间:2018-02-09 15:38:51

标签: amazon-web-services aws-lambda serverless-framework

我写了一个lambda函数,它返回S3 Buckets中文档的预先签名的URL。

代码非常简单:

            const url = s3.getSignedUrl('getObject', {
                Bucket: BUCKET_NAME,
                Key: myFile.Key,
                Expires: 20
            })

            const response = {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({
                    "url": url
                }),
            };

有趣的是当我在本地调用此函数(使用无服务器框架)时:

sls invoke local -f getEconomyFile -d '{ "queryStringParameters": { "key": "myfile.pdf" } }'

它正在工作!我有一个网址给我文件。

但是当我部署到AWS Lambda时,该函数会返回一个始终显示" access denied"在文件上:

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>93778EA364B3506B</RequestId>
    <HostId>
        yqnPC0SeIVE3/Pl7/d+xHDJ78=
    </HostId>
</Error>

为什么它在本地工作而未部署?

谢谢!

1 个答案:

答案 0 :(得分:8)

以下是预签名网址不起作用时要检查的事项列表:

  1. Lambda函数的IAM策略需要访问有问题的S3对象(通过arn:aws:s3 ::: BUCKET-NAME / *)。如果它没有访问权限,它将能够创建一个预先签名的URL(纯粹的本地计算**),但该URL实际上不允许您访问该对象(因为支持预签名URL的凭据可以没有权限。)
  2. 检查网址是否已过期。
  3. 检查客户端是否已经过时间同步。
  4. 检查网址是否在传输过程中未被修改或以某种方式编码。
  5. **您可以告诉这是一个本地计算,并且不会通过预先签署对象(例如s3:// notmybucket / fred)来调用任何对AWS的调用。这将起作用并生成一个预先签名的URL,但它实际上无法用于检索该对象。