如何允许 cognito 身份验证的用户获得对 s3 存储桶的公共访问权限

Posted

技术标签:

【中文标题】如何允许 cognito 身份验证的用户获得对 s3 存储桶的公共访问权限【英文标题】:how to allow cognito authenticated users to get public access to s3 bucket 【发布时间】:2021-10-22 08:58:40 【问题描述】:

我希望我的 Cognito 身份验证用户(通过 google 身份提供商)公开访问存储桶对象,而不需要任何 x-Amz-Security 或签名令牌。

在我的应用程序中,经过身份验证的用户每天上传 100 张图片,我无法在 Dynamodb 中存储带有令牌的每个图片 URL,因为它仅在 7 天内有效,7 天后它的令牌会更改。 访问存储桶对象的另一种方法是请求 getObject 调用,它需要一个键(文件名)并返回带有令牌(和到期)的对象/图像 URL,我可以使用它来呈现图像,但我不想进行额外调用以获取标记化的 URL。 因此,我希望经过身份验证的用户能够公开访问我存储桶中的所有对象。

为此,我正在使用 Amplify,并且可以使用 amplify add storage 在应用程序中添加存储空间。 我尝试编写存储桶策略,但它对我不起作用:


    "Version": "2012-10-17",
    "Statement": [
        
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": 
                "Federated": "accounts.google.com"
            ,
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::<bucketname>-staging"
        ,
        
            "Effect": "Allow",
            "Principal": 
                "Federated": "accounts.google.com"
            ,
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::<bucketname>-staging/*"
        
    ]

上述策略不起作用,我仍然需要一个令牌才能从 s3 存储桶访问图像/对象。 我也试过这个原理,但它允许公共访问对象,这意味着未经身份验证的用户也可以访问它。


                "AWS": "*"
            ,

在此之后,我在 Cognito 池 ID 和 google id 的帮助下创建了一个身份池。并授予它读、写和列出权限。但是经过身份验证的用户仍然需要一个签名的 URL,我想让他们使用未签名的 URL 一次性访问它。

【问题讨论】:

link 我在 amplify-cli 存储库上提出的问题。 我已经按照这篇文章创建Identity Pool 我不确定我是否理解这个问题。所以你有一个经过身份验证的用户。在身份池的帮助下,您将 ID 令牌交换为一组临时凭证。使用这些凭据,您经过身份验证的用户可以对您在策略中指定的任何资源进行getObject 调用。问题究竟出在哪里?它与 S3 的直接链接有什么关系? @AleksanderWons 实际上,我不是在前端调用 getObject 调用,我也不想这样做。我只想允许经过身份验证的用户仅使用“/public/key”URL 访问存储桶图像。不需要令牌或签名。更清楚地说,我的“限制所有公共访问”在存储桶和全局级别处于关闭状态。 【参考方案1】:

如果我正确理解您的问题,访问您不想访问的非公共 S3 对象:

将请求签名到 S3 使用提供的 API 和临时凭据

这里的问题是,要访问 S3 中的受限对象,您必须使用两种可能的机制之一:

将请求签名到 S3 使用提供的 API 和临时凭据

您需要以某种方式告诉 S3 谁在请求该文件。在您的情况下,它是联合用户。您可以通过使用从 STS 获得的安全令牌对请求进行签名或使用 SDK 将 ID 令牌交换为一组临时凭证,然后对 S3 API 进行签名调用来告诉它。

如果我理解正确 - 你不想做这两件事。在这种情况下,你就不走运了。您将无法按照您想要的方式实现您想要的。

【讨论】:

谢谢@aleksanderwons,我发现晚了,你是对的。我们要么需要一个预签名的 URL,要么需要调用 getURL 函数来从存储桶中获取图像。谈到我对 getURL 调用的关注,它不是网络调用,它只是一个本地调用,它将凭据连接到传递的密钥。所以现在我正在使用 getURL 函数。获取标记化的 URL。参考这个:(ios代码链接)[github.com/aws-amplify/aws-sdk-ios/blob/main/AWSS3/…

以上是关于如何允许 cognito 身份验证的用户获得对 s3 存储桶的公共访问权限的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Facebook验证使用Cognito的API调用?

对来自多个来源(例如 Cognito 和 Azure)的令牌进行身份验证

如何使用带有 iOS SDK 的 Facebook 身份验证通过 DynamoDB 和 Cognito 存储用户信息

Cognito - 如何在与客户端从(通过放大)获得令牌的子域不同的子域上对 nodejs 后端的客户端进行身份验证?

如何从 Cognito 身份池提供的身份凭证访问用户数据?

AWS - JavaScript - 具有经过身份验证的 Cognito 用户对 DynamoDB 的 CRUD 操作