【问题标题】:How to do DynamoDB Fine-Grained Access Control?如何做DynamoDB细粒度访问控制?
【发布时间】:2021-01-03 14:23:10
【问题描述】:

第一次发布问题,如果我没有正确解释,请告诉我。我对 AWS 还是很陌生,正在努力学习。

主要问题:测试以下设置是否按预期工作的最简单方法是什么?

我正在使用 AWS DynamoDB 尝试遵循这个想法:

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html

每个 UserId 将是他们的分区键,他们将只能读取、写入和删除有关其特定行/项目的信息。

我首先使用同名 GameScores 创建一个表

dynamodb table image

我还使用所有默认设置创建了一个名为“gamers”的用户池。

enter image description here

我使用他们在文档中的策略创建了一个策略并将其称为“dynmodbgametable”,我唯一更改的是“资源”以匹配我刚刚创建的 dynamoDB“GameScores”的 ARN。

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "AllowAccessToOnlyItemsMatchingUserID",
        "Effect": "Allow",
        "Action": [
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem",
            "dynamodb:BatchWriteItem"
        ],
        "Resource": [
            "arn:aws:dynamodb:us-..rest of arn../GameScores"
        ],
        "Condition": {
            "ForAllValues:StringEquals": {
                "dynamodb:LeadingKeys": [
                    "${www.amazon.com:user_id}"
                ],
                "dynamodb:Attributes": [
                    "UserId",
                    "GameTitle",
                    "Wins",
                    "Losses",
                    "TopScore",
                    "TopScoreDateTime"
                ]
            },
            "StringEqualsIfExists": {
                "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
            }
        }
    }
]

}

我创建了一个角色。单击受信任实体类型的 Web 身份和选择 Web 身份提供商,我从用户池“gamers”池 ID 中选择 Amazon Cognito 和身份池 ID 作为池 ID,然后附加我刚刚创建的名为“dynmodbgametable”的策略。我称这个角色为“GameRole”

enter image description here

我继续在“玩家”用户池中创建两个用户。

在这一点上,我不知道我应该做什么来测试它,看看我是否正确地遵循了这些指令。我开始设置这个 Nodejs 脚本进行测试,它可以从数据库中放入和获取内容,但我知道它使用的是保存在本地机器上的默认根信用。我想我想将“AWS.config.credentials”设置为包含用户池的内容,并放入其中一个用户名及其相关密码。但是我没有太多运气弄清楚我应该如何做到这一点。在此之前是否有必要为“游戏玩家”用户池创建客户端应用程序? 这是我正在尝试的小脚本,如果有帮助的话。

    var AWS = require("aws-sdk");


AWS.config.update({ region: "us-east-2" });


var ddb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });

var params = {
  TableName: "GameScores",
  Item: {
    UserId: { S: "user id" },
    GameTitle: { S: "hobo" },
  },
};


ddb.putItem(params, function (err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data);
  }
});

我真的不知道如何获取“${www.amazon.com:user_id}”以及在何处或如何将其传递给和传递。数据库本身是否有一些端点?我想创建某种端点来指向吗?我只知道这是确定分区键的变量。

如果我能弄清楚如何测试它是否正常工作,我觉得其中一些会为我所用。现在我觉得我不太了解概念上发生了什么。我在网上阅读的所有 YouTube 视频、文档和其他 Stack 溢出帖子似乎都只是在更高层次上谈论这个,或者不在我想要做的范围内。

感谢您提供的任何帮助!如果缺少某些内容,我一定会对其进行编辑。

可能不需要额外信息:我目前有一个 AWS Amplify Web 应用程序,该应用程序具有一个工作界面,该界面具有与用户池的工作身份验证。我想添加这种细粒度访问控制的能力,这样当用户登录时,他们将有权编辑他们的个人资料信息(姓名、年龄等),而不能查看其他个人资料信息。如果我能得到这个细粒度访问控制东西的工作原型,我应该能够弄清楚如何让它为我的 Amplify 应用程序工作。

【问题讨论】:

    标签: node.js amazon-web-services amazon-dynamodb amazon-cognito


    【解决方案1】:

    对于任何偶然发现我的帖子的人,我最终选择了一条稍微不同的路线。它可能对你没有用,但它解决了我的问题。

    因为我使用的是 AWS Amplify,所以我联系了他们(向 undef_obj 大声回答我!)他说:

    查看您的链接,您正在尝试将 IAM 策略变量用于 Cognito Identity 并制作您自己的访问控制矩阵解决方案。虽然这是可能的,但如果实施有误,将需要大量的努力和测试,并可能出现安全问题。这方面的帮助超出了 Amplify 框架的范围。但是,如果您正在寻找 Amplify 的细粒度授权,这是内置在 GraphQL Transformer @auth 指令中的,我建议您查看它。有大量示例展示了如何将 React 应用程序设置到使用 AWS AppSync 和 DynamoDB 作为后备存储的 Amplify GraphQL 端点。

    所以我对此进行了调查,发现使用 AWS AppSync 对我有用!

    我去了THIS LINK 并按照那里的一些说明进行操作。具体来说: 放大添加api 选择:GraphQl 授权类型:Amazon Cognito 用户池 (我已经将用户池添加到项目中,因此它跳过了创建新用户池的过程) 我一直选择默认值,直到“选择架构模板” 我选择了“具有细粒度访问控制的对象(例如,项目 ect 管理应用程序,具有基于所有者的授权)"

    从那里它设置了一个示例项目,我可以从中开始学习 GraphQL 以及如何实现细粒度的访问控制。使用 getPrivateNote 解析器中的代码可能是最有用的。我还使用了这个appsync starter application 来弄清楚如何从我的反应客户端与 GraphQL 进行交互。整个过程花了我好几个小时才弄清楚,目前我仍在尝试完全理解它是如何工作的,但到目前为止,这个 AppSync GraphQL 似乎是我的场景中最好的。 AppSync 的内置查询系统使测试访问控制变得更加容易(即使用一个用户登录并查看我是否只能访问自己的项目)

    这是我的 reactjs 代码在客户端最终的样子:

    import { API, graphqlOperation } from 'aws-amplify';
    import QueryUserInfo from './graphql/QueryUserInfo';
    
    ...
    
    getRequest = (evt) => {
          
        return new Promise((resolve, reject) =>
        {
          API.graphql(graphqlOperation(QueryUserInfo))
          .then((data) => {
            if(data) {
              console.log(data);
              resolve(data);
            } else {
              console.log(data);
              resolve(null);
            }
          })
          .catch((err) => {
            console.log(err);
            resolve(null);
          });
        });
      }
    

    这是实际的 QueryUserInfo.js 文件的样子:

    import gql from "graphql-tag";
    
    export default gql(`
    query QueryName {
      getUser(id: "c35...rest of cognito user id...69") {
        id
        email
        name
      }
    }`);
    

    解析器代码太长,无法发布,但我只是使用了 Amplify 的模板代码,我想我只需要更改 #set( $allowedOwners0 = $util.defaultIfNull($ctx.result.owner, []) )#set( $allowedOwners0 = $util.defaultIfNull($ctx.result.id, []) ) 因为“id”是我在 dynamoDB 表上使用的,而不是“所有者”。祝所有阅读本文的人好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 2022-01-03
      • 2018-03-23
      • 2018-06-24
      • 1970-01-01
      • 2016-12-08
      • 2014-08-11
      • 1970-01-01
      相关资源
      最近更新 更多