Lambda基于Cognito认证访问DynamoDB私有数据遇权限错误排查
我来帮你排查下这个权限问题,其实核心是你的IAM策略和Lambda调用的逻辑不匹配,咱们一步步来解决:
问题根源分析
你的IAM策略明确要求只能访问**分区键等于当前用户Cognito sub(身份ID)**的数据行,但现在的调用存在两个关键问题:
- 你从
event.queryStringParameters.user_id获取的ID不一定是用户真实的Cognito sub,不仅容易被篡改,还不符合策略的条件匹配规则; - IAM策略的Resource范围仅指定了表本身,没有覆盖表内的具体数据项,权限范围不完整。
解决方案步骤
1. 修正IAM角色权限策略
更新你的IAM策略,调整Resource范围和Condition逻辑:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:UpdateItem" ], "Resource": "arn:aws:dynamodb:XX-XXXX-X:XXXXXXX:table/tablename/*", "Condition": { "StringEquals": { "dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"] } } } ] }
- 把Resource改为
table/tablename/*,明确指向表内的所有数据项; - 将
ForAllValues:StringEquals改为StringEquals,因为我们只需要匹配单个分区键值,ForAllValues适用于批量操作的多值场景。
2. 在Lambda中正确获取用户的Cognito身份ID
Lambda需要从认证上下文里获取用户的真实Cognito sub,而不是从查询参数中取值:
- 如果是API Gateway + Cognito Identity Pool触发,用户身份ID在
event.requestContext.identity.cognitoIdentityId中; - 如果是API Gateway + Cognito User Pool Authorizer触发,用户的sub在
event.requestContext.authorizer.claims.sub中。
3. 修正Lambda的getItem调用代码
用获取到的真实Cognito sub作为查询Key,示例代码(以Cognito Identity Pool为例):
const AWS = require('aws-sdk'); const ddb = new AWS.DynamoDB({ apiVersion: 'latest' }); exports.handler = async (event) => { // 获取当前用户的Cognito身份ID const userSub = event.requestContext.identity.cognitoIdentityId; if (!userSub) { return { statusCode: 401, body: JSON.stringify('Unauthorized: No valid user identity found') }; } const params = { TableName: 'tablename', Key: { 'id': { S: userSub } // 用用户的Cognito sub作为分区键值 } }; try { const data = await ddb.getItem(params).promise(); return { statusCode: 200, body: JSON.stringify(data) }; } catch (err) { console.error("Error fetching user data:", err); return { statusCode: 500, body: JSON.stringify('Failed to retrieve user data') }; } };
- 改用
async/await写法,比回调更易维护; - 先校验用户身份是否存在,避免无权限调用;
- 确保DynamoDB表的分区键
id存储的是用户的Cognito sub值,这样才能匹配策略条件。
额外检查点
- 确认DynamoDB表的分区键确实是
id,且类型为字符串(S型); - 确认API Gateway已正确配置Cognito认证,确保用户身份能传递到Lambda的
event参数中; - 确认Lambda执行角色已正确应用更新后的IAM策略,且策略中的区域、账号ID、表名均无误。
内容的提问来源于stack exchange,提问作者AleCat83
相关产品推荐
相关产品推荐

