Amplify GraphQL API限制Lambda解析器仅所有者调用的配置问题
我在schema.graphql文件中编写了如下定义:
type Floorplan @model @auth(rules: [ { allow: private, operations: [read], provider: userPools }, { allow: owner, provider: userPools } ]) @aws_cognito_user_pools { id: ID! @primaryKey name: String! bedrooms: Int! } input FloorplanInput { id: ID! name: String! bedrooms: Int! } type Mutation { floorplanLambda(input: FloorplanInput): Floorplan @function(name: "floorplanLambda-${env}") @aws_cognito_user_pools }
创建上述Lambda函数的目的是在更新Floorplan数据前执行自定义校验,但当前存在两个问题:
- 所有已认证用户都可以修改其他用户的Floorplan数据,原本以为添加
@aws_cognito_user_pools指令即可解决权限问题,但实际并未生效 - 使用authMode为
AMAZON_COGNITO_USER_POOLS调用floorplanLambda时,收到报错:"Not Authorized to access floorplanLambda on type Floorplan"
核心诉求:需要增加什么配置才能锁定floorplanLambda函数的访问权限,使其仅能被对应Floorplan模型的所有者成功调用?
@aws_cognito_user_pools指令仅校验请求是否来自合法的Cognito认证用户,不会自动关联@model类型上配置的owner权限规则。自定义Mutation字段的权限默认完全独立,不会继承对应模型的auth配置,你现在碰到的两个问题本质都是没给自定义字段单独配置匹配的授权规则,导致AppSync要么放通所有认证用户的请求,要么直接在请求到达Lambda前就拦截返回无权限。
分两步配置即可解决:
1. 给自定义Mutation字段显式添加owner授权规则
不要只加@aws_cognito_user_pools,要和Floorplan模型对齐auth规则,修改Mutation定义如下:
type Mutation { floorplanLambda(input: FloorplanInput): Floorplan @function(name: "floorplanLambda-${env}") @auth(rules: [ { allow: owner, provider: userPools, operations: [update] } ]) @aws_cognito_user_pools }
注意:如果你的Floorplan模型自定义了
ownerField参数(没有用默认的owner字段存所有者信息),要在这条auth规则里同步加上相同的ownerField配置,否则权限识别会出错。
2. 在Lambda代码中添加二次所有权校验
@auth的owner规则在自定义Lambda resolver场景下,不会自动查询目标Floorplan记录比对所有者,必须在Lambda业务逻辑里手动加校验,否则恶意用户构造请求传假的owner值就能绕过schema层校验:
- 从Lambda触发事件的
identity.claims对象里,提取当前调用用户的Cognitosub值(用户唯一标识) - 拿入参里的Floorplan
id,查询DynamoDB中对应的目标记录 - 比对记录中存储的owner字段值和当前用户的
sub,不一致直接返回403无权限错误,匹配通过后再执行你原本的自定义校验、数据更新逻辑
配置完成后先执行amplify codegen models确保最新auth规则被正确编译,再运行amplify push部署即可,不会再出现无权限报错,也能阻止非所有者修改他人的Floorplan数据。
内容的提问来源于stack exchange,提问作者BatteryAcid

