我创建了一个表,其中 partitionKey 作为“id”以及其他属性,例如:firstName、lastName 等...我还创建了一个 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。
我尝试过遵循各种教程和文档,但到目前为止我找不到任何有用的东西。
不要将投影表达式设置为空字符串,这会导致不良结果:
ProjectionExpression: isOwner ? "" : "id, firstName, lastName"