无法使用 AWS Lambda、API Gateway 和 IAM 策略从 DynamoDB 表返回正确的值

问题描述 投票:0回答:1

我创建了一个表,其中 partitionKey 作为“id”以及其他属性,例如:firstNamelastName 等...我还创建了一个 AWS Lambda,我可以使用 API Gateway 与此 IAM 权限进行交互政策:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
        ],
        "Resource": "arn:aws:logs:xxxxxxx/aws/lambda/test-production:log-stream:*",
        "Effect": "Allow"
    },
    {
        "Sid": "1",
        "Effect": "Allow",
        "Action": [
            "dynamodb:GetItem",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem"
        ],
        "Resource": "arn:aws:dynamodb:xxxxxxxxxxxxxxxxxxx/xxxxxxx",
        "Condition": {
            "ForAllValues:StringEquals": {
                "dynamodb:LeadingKeys": "${cognito-identity.amazonaws.com:sub}"
            }
        }
    },
    {
        "Sid": "2",
        "Effect": "Allow",
        "Action": [
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query"
        ],
        "Resource": "arn:aws:dynamodb:xxxxxxxxxxxxxxx/xxxxx",
        "Condition": {
            "ForAllValues:StringEquals": {
                "dynamodb:Attributes": [
                    "id",
                    "firstName",
                    "lastName"
                ]
            },
            "StringEqualsIfExists": {
                "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
            }
        }
    }
]
}

此策略的目标是让普通用户只能读取特定属性:如 id、firstName、lastName 等...并且仅让对象的所有者通过检查来自 Cognito 用户帐户的“sub”。

这是我使用 ExpressJS 在 AWS Lambda 中实现的:

app.get("/user/:id", async function (req, res) {


const partitionKey = req.params.id;

  const authProvider =
    req.apiGateway.event.requestContext.identity.cognitoAuthenticationProvider;
  const [userId] = authProvider.match(IDP_REGEX);

  const isOwner =
    userId != null && userId != undefined && userId === partitionKey;

  const getItemParams = {
    TableName: tableName,
    Key: {
      id: partitionKey,
    },
    ProjectionExpression: isOwner ? "" : "id, firstName, lastName",
  };

  try {
    const data = await ddbDocClient.send(new GetCommand(getItemParams));

    if (!data.Item) {
      res.statusCode = 404;
      return res.json({ error: "Item not found", url: req.url });
    }

    res.json({
      success: "get call succeed!",
      url: req.url,
      body: req.body,
      data,
    });
  } catch (error) {
    res.statusCode = 500;
    res.json({ error, url: req.url, body: req.body });
  }
});

当我使用对象所有者的帐户登录时,调用失败并出现 502 错误,但当我注销并检索特定属性时,它可以工作。我无法理解如何根据该 IAM 策略实施 Lambda。

我尝试过遵循各种教程和文档,但到目前为止我找不到任何有用的东西。

amazon-web-services aws-lambda amazon-dynamodb amazon-cognito api-gateway
1个回答
0
投票

不要将投影表达式设置为空字符串,这会导致不良结果:

ProjectionExpression: isOwner ? "" : "id, firstName, lastName"

© www.soinside.com 2019 - 2024. All rights reserved.