【发布时间】:2020-01-07 18:03:44
【问题描述】:
在我的应用程序中,用户可以创建不同类型的帖子。这些帖子有不同级别的隐私(私人、仅限朋友、公开)。我想在用户处于“草稿”阶段时将所有帖子设为私有。
我的计划是让我的 Cognito 用户池中的授权用户访问仅与其用户 ID 对应的 Elasticsearch 索引(从 Cognito 用户获得的sub 属性)。
首先,用户向 API Gateway 发出请求并通过 Cognito Authorizer。接下来,如果他们通过了身份验证,他们就会到达这个(当前是准系统)Lambda 函数,该函数向与其用户 ID 匹配的索引发出 PUT 请求:
// Runtime: Node.js 10.x
const AWS = require("aws-sdk");
const uuidv4 = require("uuid/v4");
const axios = require("axios");
exports.handler = async (event) => {
const {userId, draftData} = event; // userId value passed through from API Gateway
const esEndpoint = `https://<MY_ES_ENDPOINT>/${userId}/drafts`;
const newDraft = {
id: uuidv4(),
content: draftData
};
try {
const result = await axios.put(esEndpoint, newDraft);
return result.data;
} catch(err) {
console.log("Err: ", err);
return err;
}
};
在测试函数时,我收到此错误:User: anonymous is not authorized to perform: es:ESHttpPut。
我的 Lambda 函数具有以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "es:ESHttpPut",
"Resource": "arn:aws:es:<region>:<account-id>:domain/<domain-name>"
}
]
}
我的 Elasticsearch 域具有以下访问策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account-id>:root"
},
"Action": "es:*",
"Resource": "arn:aws:es:<region>:<account-id>:domain/<domain-name>/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account-id>:role/service-role/<lambda-role-name>"
},
"Action": "es:ESHttpPut",
"Resource": "arn:aws:es:<region>:<account-id>:domain/<domain-name>/*"
}
]
}
我知道我需要签署对 Elasticsearch 端点的请求才能解决此问题。但是我怎样才能为每个单独的 Cognito 用户做到这一点?我应该如何签署请求并使用axios 发送?
我应该如何修复我的策略以允许这些用户正确访问我的 Elasticsearch 域?
编辑
有人知道如何仅使用 IAM 用户凭证创建签名吗?我尝试使用aws4 库并得到403 Forbidden 错误,也尝试使用the example in the aws docs themselves 但收到相同的403 错误。
如果我能成功地向 Elasticsearch 发出请求,我会很高兴;
感谢任何帮助。谢谢。
【问题讨论】:
-
这有什么有效的答案吗?
标签: node.js amazon-web-services elasticsearch amazon-cognito amazon-iam