AWS Amplify GraphQL未授权错误:无法访问Objective的employee字段
问题原因及解决方案
核心原因
当查询Objective的employee关联字段时,Amplify会单独触发Profile类型的授权模板与Resolver,而非复用Objective的授权逻辑。如果Profile的授权配置未同步处理租户关联逻辑,或未利用关联查询的上下文信息,就会出现授权失败。
具体触发场景
- 关联查询的独立授权流程:
@belongsTo关联的解析会发起独立的Profile查询请求,该请求会使用Profile自身的授权模板。若Profile的授权逻辑未包含与Objective一致的租户过滤规则,直接触发权限校验失败。 - 关联上下文未被利用:在
Profile的授权模板中,默认不会自动继承父对象(Objective)的tenant信息,若未手动从$ctx.source(父对象数据)中获取tenant并添加过滤,授权逻辑无法匹配到对应租户的Profile数据。 - 数据一致性问题:若
Objective的tenant与关联Profile的tenant值不一致,即使授权逻辑正确,也会因租户不匹配被过滤,返回null。
解决方案
1. 同步Profile的授权模板逻辑
确保Profile类型使用与Objective相同的自定义授权模板,同时添加关联上下文的租户过滤:
## [Start] Authorization Steps for Profile ** $util.qr($ctx.stash.put("hasAuth", true)) #set( $isAuthorized = false ) #set( $primaryFieldMap = {} ) #if( $util.authType() == "User Pool Authorization" ) #if( !$isAuthorized ) #set( $authFilter = [] ) #set( $ownerClaim0 = $util.defaultIfNull($ctx.identity.claims.get("sub"), null) ) #set( $currentClaim1 = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), null)) ) #if( !$util.isNull($ownerClaim0) && !$util.isNull($currentClaim1) ) #set( $ownerClaim0 = "$ownerClaim0::$currentClaim1" ) #if( !$util.isNull($ownerClaim0) ) $util.qr($authFilter.add({"owner": { "eq": $ownerClaim0 }})) #end #end #set( $role0_0 = $util.defaultIfNull($ctx.identity.claims.get("sub"), null) ) #if( !$util.isNull($role0_0) ) $util.qr($authFilter.add({"owner": { "eq": $role0_0 }})) #end #set( $role0_1 = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), null)) ) #if( !$util.isNull($role0_1) ) $util.qr($authFilter.add({"owner": { "eq": $role0_1 }})) #end ## 新增:处理关联查询的父对象租户 #if( $ctx.source && $ctx.source.tenant ) $util.qr($authFilter.add({"tenant": { "eq": $ctx.source.tenant }})) #end ## 原有租户admin逻辑 #if( $groupsInToken.contains("tenant-admin") ) #foreach( $group in $groupsInToken ) $util.qr($authFilter.add({"tenant": { "eq": $group }})) #end #end ## end custom auth #if( !$authFilter.isEmpty() ) $util.qr($ctx.stash.put("authFilter", { "or": $authFilter })) #end #end #end #if( !$isAuthorized && $util.isNull($ctx.stash.authFilter) ) $util.unauthorized() #end $util.toJson({"version":"2018-05-29","payload":{}}) ## [End] Authorization Steps for Profile **
2. 校验数据一致性
确保所有Objective关联的Profile记录,其tenant字段值与Objective的tenant完全一致。可通过数据库查询或Amplify控制台验证数据。
3. 验证令牌中的租户声明
确认预令牌生成Lambda添加的groupsInToken包含正确的租户ID,且该声明能在Profile的授权上下文($ctx.identity.claims)中正常访问。
内容的提问来源于stack exchange,提问作者Leon Schmidt
相关产品推荐
相关产品推荐

