【问题标题】:best way to provide a single S3 bucket for each Cognito identity in a pool为池中的每个 Cognito 身份提供单个 S3 存储桶的最佳方式
【发布时间】:2017-09-23 19:40:40
【问题描述】:

我正在评估在平台中使用 Cognito 开发人员身份验证身份和 S3 存储的选项。本质上,我想做的是为每个客户创建一个单独的 S3 存储桶和 Cognito 身份。此时,我们不需要为每个用户提供单独的 Cognito 身份,我们只使用身份来允许访问 S3 存储。在这种情况下,我们将需要支持数百个客户(因此需要数百个具有关联 Cognito 身份的存储桶)。

我发现了几个如何使用单个 S3 存储桶中的专用文件夹来执行此操作的示例(请参阅 Example 1Example 2)。在我们的案例中,我不认为针对所有客户的单个存储桶将是可行的解决方案,原因有几个(其中一个原因是 S3 API 速率限制显然与唯一存储桶相关联)。

我已尝试在客户存储桶上创建访问策略以仅允许访问特定 Cognito 身份,即

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::CUSTOMER-BUCKET/*"
      ],
      "Principal": {
        "AWS": "my IAM role for Cognito"
      },
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:sub": [
            "us-east-1:customer's cognito identity"
          ]
        }
      }
    }
  ]
}

但 S3 无法识别 cognito-identity.amazonaws.com:sub 条件。

如果我将类似的策略附加到用于 Cognito 身份池的 IAM 角色,即

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::CUSTOMER-BUCKET/*"
      ],
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:sub": [
            "us-east-1:customer's cognito identity"
          ]
        }
      }
    }
  ]
}

这似乎可行,但显然我必须为每个身份和存储桶组合添加一个策略,这会遇到可以添加到单个角色(总共 10240 个字符)的内联策略大小的限制。

在这一点上,我正在摸不着头脑,试图想出一种可行的方法。任何建议将不胜感激。

【问题讨论】:

    标签: amazon-s3 amazon-cognito


    【解决方案1】:

    您绝对应该使用一个存储桶,而不是每个用户一个存储桶。甚至不要考虑“每用户存储桶”策略。

    您应该考虑使用IAM Policy Variables 创建一个适用于所有用户的策略。

    您可以在 S3 策略中使用 Cognito ID 作为前缀。请参阅 IAM Roles 文档中的 S3 前缀 部分:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": ["s3:ListBucket"],
          "Effect": "Allow",
          "Resource": ["arn:aws:s3:::mybucket"],
          "Condition": {"StringLike": {"s3:prefix": ["${cognito-identity.amazonaws.com:sub}/*"]}}
        },
        {
          "Action": [
            "s3:GetObject",
            "s3:PutObject"
          ],
          "Effect": "Allow",
          "Resource": ["arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/*"]
        }
      ]
    }
    

    然后用户可以访问同一 S3 存储桶的子目录中的对象。

    关于使用单桶的问题,我建议你尝试一下,然后看看是否真的会出现问题。 Amazon S3 具有高度可扩展性,并被一些非常大的 Web 服务使用,因此它很可能支持您的用例。见:Amazon S3 Request Rate and Performance Considerations

    【讨论】:

    • 我正在尝试使用“每个公司一个桶”策略,而不是每个用户。每家公司可能有成百上千的用户,但每家公司只有一个 Cognito 身份。我熟悉 S3 请求率和性能注意事项,这就是为什么我想将访问分散到多个存储桶中。我确信共享一个存储桶的所有用户在某些时候都会成为问题。很快就会开始突破每桶 100 个请求/秒的限制。我想我将不得不从亚马逊那里得到一些关于如何处理这个问题的建议。
    • 我建议你先试试看,然后再做一些奇怪的事情来避免你可能没有的问题。像 DropBox 这样的公司已经将 S3 用于更大规模的事情(但我不知道他们的存储桶设置)。
    • John 回答中的示例是 Cognito 推荐的通过 Cognito 缩减对 S3 存储桶的访问的方法。它允许您避免您提到的角色限制。我的第一个建议是尝试他所说的,使用一个桶。如果您发现这确实是阻塞的,您也许可以向角色中的资源数组添加其他属性?
    猜你喜欢
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2020-09-23
    • 2019-03-30
    • 1970-01-01
    • 2020-09-28
    • 2018-07-12
    • 2021-01-07
    相关资源
    最近更新 更多