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

Lambda调用DynamoDB PutItem报AccessDeniedException权限错误排查

问题根因

你的代码根本没有使用Cognito联邦身份对应的临时凭证,报错已经把问题说的很清楚了:当前调用DynamoDB用的身份是Lambda自带的执行角色CreateProfileFunctionRole-1VOW05TI1WR20,不是你给Cognito用户组关联的那个角色。你给Cognito角色附加AdministratorAccess完全加错了对象,当前做权限校验的是Lambda执行角色,它没有DynamoDB表的写权限。

你写的boto3.Session(region_name='eu-west-2')没有传入任何自定义凭证,boto3会按照默认凭证链读取Lambda运行环境内置的执行角色凭证,完全感知不到你Cognito用户登录拿到的身份信息。你用jwt解析id_token能看到角色关联信息,不代表这个角色的凭证会自动被boto3使用——id_token只是身份声明,调用AWS服务必须用对应的临时IAM凭证三件套(AccessKey、SecretKey、SessionToken),你不手动传入的话,代码不会自动用这个身份。


对应解决方案

根据你实际的权限设计选一种就行:

方案1:用Lambda执行角色访问DynamoDB(最常用的服务端代理模式)

这种模式下不需要让用户直接有DynamoDB权限,所有DynamoDB操作都由Lambda代执行,你只需要:

  • 打开IAM控制台,找到报错里提到的Lambda执行角色arn:aws:sts::<ACCOUNT_ID>:assumed-role/<PREFIX>-CreateProfileFunctionRole-1VOW05TI1WR20
  • 给这个角色附加DynamoDB的PutItem权限(或者你要加AdministratorAccess也直接加在这个角色上,别加给Cognito角色)
  • 代码里不需要手动建Session,直接用默认客户端就行,Lambda会自动管理凭证轮转:
import boto3
import json
import uuid

# 初始化客户端放函数外,复用连接提升性能
ddb_client = boto3.client('dynamodb', region_name='eu-west-2')

def create_profile(event, context):
    profile = json.loads(event["body"])
    row_id = str(uuid.uuid4())
    item = {
        'RowID': {'S': row_id},
        'first_name': {'S': profile['first_name']},
        'last_name': {'S': profile['last_name']}
    }
    ddb_client.put_item(TableName='Persons', Item=item)

方案2:透传Cognito用户身份,用用户的联邦凭证访问DynamoDB

如果你需要严格以登录Cognito用户的身份做DynamoDB权限控制,那你需要手动从API Gateway透传的事件里拿到Cognito联邦身份对应的临时凭证,传入boto3 Session:

  • 首先确认你的API Gateway授权配置正确,会把Cognito Identity Pool分发的临时凭证三件套透传到Lambda的event上下文里,一般在event['requestContext']['authorizer']路径下
  • 修改代码,用拿到的用户凭证初始化boto3会话:
import boto3
import json
import uuid

def create_profile(event, context):
    profile = json.loads(event["body"])
    # 从API Gateway授权上下文中提取Cognito联邦身份的临时凭证,字段路径根据你实际的API配置调整
    auth_ctx = event['requestContext']['authorizer']
    user_session = boto3.Session(
        aws_access_key_id=auth_ctx['accessKey'],
        aws_secret_access_key=auth_ctx['secretKey'],
        aws_session_token=auth_ctx['sessionToken'],
        region_name='eu-west-2'
    )
    ddb_client = user_session.client('dynamodb')
    
    row_id = str(uuid.uuid4())
    item = {
        'RowID': {'S': row_id},
        'first_name': {'S': profile['first_name']},
        'last_name': {'S': profile['last_name']}
    }
    ddb_client.put_item(TableName='Persons', Item=item)

这种模式下你给Cognito用户组关联角色加的DynamoDB权限才会生效。


补充排查点:如果你确认已经给对应角色加了权限还是报同样的错,先检查策略里的资源ARN是不是和你实际的表完全匹配,有没有写错区域、表名、账号ID,有没有存在策略条件限制。

内容的提问来源于stack exchange,提问作者Sandeep

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:54:25