Amazon web services Lambda/预签名url访问被拒绝

Amazon web services Lambda/预签名url访问被拒绝,amazon-web-services,aws-lambda,serverless-framework,Amazon Web Services,Aws Lambda,Serverless Framework,我编写了一个lambda函数,它为S3存储桶中的文档返回一个预先签名的url 代码非常简单: const url = s3.getSignedUrl('getObject', { Bucket: BUCKET_NAME, Key: myFile.Key, Expires: 20 }) const response = {

我编写了一个lambda函数,它为S3存储桶中的文档返回一个预先签名的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" } }'
它起作用了!我有一个给我文件的url

但当我部署到AWS Lambda时,函数返回一个URL,该URL在文件上始终显示“拒绝访问”:

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>93778EA364B3506B</RequestId>
    <HostId>
        yqnPC0SeIVE3/Pl7/d+xHDJ78=
    </HostId>
</Error>
为什么它在本地工作而没有部署


谢谢大家!

这里列出了当预签名URL不起作用时要检查的事项:

  • Lambda函数的IAM策略需要访问相关的S3对象(通过arn:aws:S3:::BUCKET-NAME/*)。如果它没有访问权限,它将能够创建一个预签名URL(纯本地计算**),但该URL实际上不允许您访问该对象(因为支持预签名URL的凭据没有访问权限)
  • 检查URL是否未过期
  • 检查用于签名URL的凭据是否尚未过期。当使用临时凭据对URL进行预签名时,如果凭据在预签名URL过期之前过期,则这是一个常见问题
  • 检查客户端是否进行了时间同步
  • 检查URL是否在传输过程中被损坏或以某种方式编码

  • **您可以通过预签名对象(如s3://notmybucket/fred)来判断这是一个本地计算,并且不涉及对AWS的任何调用。这将起作用并生成一个预签名的URL,但它实际上无法用于检索该对象。

    您的签名URL在生成后20秒过期。有没有可能只是过期了?默认值是15m。不,我试图删除Expires参数,但不是:-/Lambda函数使用的IAM角色是否真的允许S3 GetObject访问相关的bucket?预签名URL生成本身不会对afaik中的凭据进行任何验证。如果不是这样,那么我会检查预签名的URL是否有损坏,以及您的客户端是否进行了时间同步,在我的无服务器文件配置中:iamRoleStatements:-效果:允许操作:s3:*资源:arn:aws:s3::BUCKET-NAME。您还需要通过arn:aws:s3:::BUCKET-NAME/*未来的谷歌用户:注意星号!我花了相当长的时间调试我认为是客户端上传方面的问题。。。事实证明,IAM用户对
    arn:aws:S3:::BUCKET-NAME
    有“所有S3操作”,这看起来是正确的。为什么不呢?将其更改为
    arn:aws:s3:::BUCKET-NAME*
    解决了此问题。@anonymouscoward我猜您是想编写arn:aws:s3:::BUCKET-NAME/*(带尾随斜杠星号)而不是arn:aws:s3:::BUCKET-NAME*(带尾随星号)。