基于顶层模型字段实现AWS Amplify Gen 2按模型授权
解决方案:AWS Amplify Gen 2 组织级模型授权实现
方案1:基于关系的自定义谓词授权(推荐)
直接利用Amplify Gen 2的模型关联和自定义谓词,无需同步字段到下属模型,直接通过关联的Organization实例校验权限。
模型定义示例
import { type ClientSchema, a, defineData } from '@aws-amplify/backend'; const schema = a.schema({ Organization: a.model({ name: a.string(), // 存储成员用户ID列表 members: a.string().array(), // 存储管理员用户ID列表 admins: a.string().array(), // 关联下属模型,比如Project projects: a.hasMany('Project', 'organizationId') }) .authorization([ // 组织管理员可修改组织本身 a.allow('groups', ({ identity }) => ({ groups: identity.groups || [] })), // 成员可查看组织 a.allow('public', ({ auth, model }) => ({ condition: a.contains(model.members, auth.userId) })) ]), Project: a.model({ name: a.string(), organizationId: a.id(), organization: a.belongsTo('Organization', 'organizationId') }) .authorization([ // 成员仅允许read操作 a.allow('public', ({ auth, model, operation }) => ({ condition: a.and( a.eq(operation, 'read'), a.contains(model.organization.members, auth.userId) ) })), // 管理员允许所有操作 a.allow('public', ({ auth, model }) => ({ condition: a.contains(model.organization.admins, auth.userId) })) ]) }); export const data = defineData({ schema, authorizationModes: { defaultAuthorizationMode: 'userPool' } });
说明
- 下属模型通过
belongsTo关联Organization,授权规则直接访问model.organization.members/admins校验用户身份 - 利用
operation参数区分操作类型,给成员和管理员分配不同权限边界 - 无需手动同步字段,Amplify自动处理关联查询的权限校验逻辑
方案2:优化自定义Lambda授权
Lambda授权函数可从请求上下文直接获取操作类型、模型信息和用户身份,无需额外注入配置,通过查询Organization数据完成权限判断。
Lambda函数核心代码示例
const AWS = require('aws-sdk'); const dynamodb = new AWS.DynamoDB.DocumentClient(); exports.handler = async (event) => { const { operation, identity } = event; const userId = identity.username; // 从请求参数或数据源中提取关联的组织ID const organizationId = event.arguments.input?.organizationId || event.source?.organizationId; if (!organizationId) { return { allow: false }; } // 查询目标组织的成员/管理员列表 const orgResult = await dynamodb.get({ TableName: 'Organization-<your-api-id>-<env>', Key: { id: organizationId } }).promise(); const org = orgResult.Item; if (!org) { return { allow: false }; } // 根据操作类型返回权限判断结果 if (operation === 'read') { return { allow: org.members.includes(userId) || org.admins.includes(userId) }; } else { // create/update/delete 等写操作 return { allow: org.admins.includes(userId) }; } };
说明
- 从
event.operation获取当前操作类型(read/create/update/delete等) - 从
event.arguments.input(创建/更新场景)或event.source(关联数据查询场景)提取组织ID - 在Amplify模型中配置使用该Lambda授权:
.authorization([ a.allow('custom', { handler: 'arn:aws:lambda:region:account:function:function-name' }) ])
方案3:用户池自定义属性+动态授权规则
若用户规模较小,可将用户所属的组织ID和角色存储在Cognito用户池自定义属性中(例如custom:orgs格式为org1:admin,org2:member),然后在授权规则中解析属性判断权限。注意自定义属性有长度限制,仅适合小型场景。
内容的提问来源于stack exchange,提问作者ThisIsNoZaku
相关产品推荐
相关产品推荐

