【问题标题】:Lambda / Pre-signed url access deniedLambda / 预签名 URL 访问被拒绝
【发布时间】:2018-07-20 10:15:21
【问题描述】:

我编写了一个 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" } }'

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

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

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

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

谢谢!

【问题讨论】:

  • 您的签名 URL 在生成 20 秒后过期。有没有可能它只是过期了?默认为 15m。
  • 不,我试图删除 Expires 参数,但不是这样:-/
  • Lambda 函数使用的 IAM 角色实际上是否允许 S3 GetObject 访问相关存储桶?预签名 URL 生成本身不会对 afaik 凭据进行任何验证。如果不是这样,那么我会检查预签名的 URL 是否以某种方式损坏,并且您的客户端是否已进行时间同步。
  • 似乎不是这样,在我的无服务器文件配置中:iamRoleStatements: - 效果:允许操作:s3:* 资源:arn:aws:s3:::BUCKET-NAME。
  • 您还需要通过 arn:aws:s3:::BUCKET-NAME/* 获得对象权限

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


【解决方案1】:

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

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

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

【讨论】:

  • 未来的 Google 员工:注意那个星号!我花了很长时间调试我认为是客户端上传方面的问题......结果,IAM 用户对arn:aws:s3:::BUCKET-NAME 有“所有 S3 操作”,看起来是正确的。为什么不?将其更改为 arn:aws:s3:::BUCKET-NAME* 解决了该问题。
  • @anonymouscoward 我猜你的意思是写 arn:aws:s3:::BUCKET-NAME/* (带有斜杠星号)而不是 arn:aws:s3:::BUCKET- NAME*(只有尾随星号)。
猜你喜欢
  • 2018-01-16
  • 1970-01-01
  • 2019-08-30
  • 2013-01-03
  • 2017-10-03
  • 2021-09-07
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
相关资源
最近更新 更多