You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda基于Cognito认证访问DynamoDB私有数据遇权限错误排查

我来帮你排查下这个权限问题,其实核心是你的IAM策略和Lambda调用的逻辑不匹配,咱们一步步来解决:

问题根源分析

你的IAM策略明确要求只能访问**分区键等于当前用户Cognito sub(身份ID)**的数据行,但现在的调用存在两个关键问题:

  1. 你从event.queryStringParameters.user_id获取的ID不一定是用户真实的Cognito sub,不仅容易被篡改,还不符合策略的条件匹配规则;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:03:26