简体   繁体   English

Lambda / 预签名 url 访问被拒绝

[英]Lambda / Pre-signed url access denied

I wrote a lambda function who return a pre-signed url for documents in S3 Buckets.我写了一个 lambda function,它为 S3 存储桶中的文档返回了一个预签名的 url。

The code is really simple:代码非常简单:

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

The funny thing is when I call this function locally (with serverless framework) like this:有趣的是,当我在本地(使用无服务器框架)调用这个 function 时,如下所示:

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

It's working.它的工作。 I have a url which give me the file.我有一个 url 给我文件。

But when I deploy to AWS Lambda, the function return a URL which always says "access denied" on the file:但是当我部署到 AWS Lambda 时,function 返回一个 URL,它总是在文件上显示“访问被拒绝”:

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

Why is it working locally and not deployed?为什么它在本地工作而不是部署?

Thank you !谢谢 !

Here's a list of things to check when pre-signed URLs do not work:以下是预签名 URL 不起作用时要检查的事项列表:

  1. The IAM policy of the Lambda function needs to have access to the S3 object in question (via arn:aws:s3:::BUCKET-NAME/*). Lambda 函数的 IAM 策略需要有权访问相关 S3 对象(通过 arn:aws:s3::::BUCKET-NAME/*)。 If it doesn't have access, it will be able to create a pre-signed URL (a purely local computation**) but that URL will not actually allow you to access the object (because the credentials underpinning the pre-signed URL do not have access).如果它没有访问权限,它将能够创建一个预签名的 URL(纯粹的本地计算**),但该 URL 实际上不允许您访问该对象(因为支持预签名 URL 的凭据确实无法访问)。
  2. Check that the URL hasn't expired.检查 URL 是否未过期。
  3. Check that the credentials used to sign the URL haven't expired.检查用于签署 URL 的凭据是否未过期。 This is a common problem when using temporary credentials to pre-sign URLs where the credentials expire before the pre-signed URL expires.当使用临时凭证预签名 URL 时,这是一个常见问题,其中凭证在预签名 URL 到期之前到期。
  4. Check that the client is time-synced.检查客户端时间是否同步。
  5. Check that the URL hasn't been mangled in transit or encoded in some way.检查 URL 是否在传输过程中没有被破坏或以某种方式编码。

** you can tell this is a local computation and does not involve any calls into AWS by pre-signing an object such as s3://notmybucket/fred. ** 您可以通过预先签署一个对象(例如 s3://notmybucket/fred)来判断这是一个本地计算,并且不涉及对 AWS 的任何调用。 That will work and generate a pre-signed URL, but it will not actually be usable to retrieve that object.这将起作用并生成一个预先签名的 URL,但它实际上不能用于检索该对象。

https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-owner-full-control-acl/ https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-owner-full-control-acl/

As access to a bucket is given to other accounts, if they put an object in the bucket, the account owner doesn't get automatic access to those put files.由于其他帐户可以访问存储桶,因此如果他们将 object 放入存储桶中,则帐户所有者不会自动访问这些放置文件。 To fix this you need to add this to your commands:要解决此问题,您需要将其添加到您的命令中:

--acl bucket-owner-full-control

Such as

aws s3api put-object --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control

or或者

aws s3 cp s3://accountA-bucket/test.txt s3://accountB-bucket/test2.txt --acl bucket-owner-full-control

Otherwise you leave the ACL for the object hyper specific to the other account and user that pushed the file.否则,您将 object hyper 的 ACL 留给推送该文件的其他帐户和用户。

Hope that helps.希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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