ABP vNext Identity 模块:用户、角色、权限、组织完整协作机制

一、先理清核心表之间的关联关系

1. 基础实体主表

  1. AbpUsers(用户):每一条代表系统登录账号,带TenantId租户隔离
  2. AbpRoles(角色):权限集合分组载体,租户隔离
  3. AbpOrganizationUnits(OU组织/部门):树形部门架构,租户隔离
  4. AbpPermissions(权限定义):代码预先定义的所有操作权限Key(如Users.Create
  5. AbpPermissionGroups(权限分组):后台界面权限分类(用户管理、订单管理)

2. 多对多中间关联表(桥梁)

  1. AbpUserRoles:用户 ↔ 角色(一个用户多个角色,一个角色多个用户)
  2. AbpUserOrganizationUnits:用户 ↔ 部门(用户可归属多个部门)
  3. AbpOrganizationUnitRoles:部门 ↔ 角色(整个部门全员自动继承该角色权限)
  4. AbpPermissionGrants(核心授权表)统一存储所有授权关系
    这张表是整个权限体系的枢纽,一条记录代表「某个对象拥有某条权限」,支持4种授权对象:
    • 按角色授权:填RoleId
    • 按用户直接授权:填UserId
    • 按部门授权:填OrganizationUnitId
    • 按租户全局授权:填TenantId
      一条记录绑定一条PermissionId,同时支持允许/拒绝权限标记

3. 附加身份声明表(Claim)

  • AbpUserClaims:给单个用户附加自定义身份(工号、手机号类型)
  • AbpRoleClaims:给角色批量附加声明,该角色下所有用户自动继承

二、四层权限继承链路(用户最终权限合并逻辑)

用户登录后,ABP会自动合并4层来源的所有权限,取并集;任意一层拒绝则直接否决:

链路优先级(从全局到个人)

  1. 租户全局权限(AbpPermissionGrants.TenantId)
    整个租户所有用户默认拥有的权限,比如租户全部员工可查看首页
  2. 用户所属部门权限(OU)
    • 先查用户所属所有OU(AbpUserOrganizationUnits)
    • 查每个OU绑定的角色(AbpOrganizationUnitRoles)→ 取角色权限
    • 再查直接给OU授予的权限(AbpPermissionGrants.OrganizationUnitId)
  3. 用户绑定角色权限(核心RBAC)
    • 通过AbpUserRoles拿到用户全部角色
    • 查询每个角色在AbpPermissionGrants中分配的权限
  4. 用户单独直接授权(个性化权限)
    给单个用户单独加/减权限,不影响同角色其他人,存在AbpPermissionGrants.UserId

合并规则:四层所有「允许权限」合并;只要任意一层标记「拒绝权限」,该权限直接失效。

直观示例

租户A全局开放【查看客户】;
用户张三归属「销售一部」部门,部门绑定角色【销售专员】(拥有【新增客户】);
张三额外绑定角色【组长】(拥有【导出客户】);
管理员给张三单独授予【删除客户】;
最终张三完整权限:查看、新增、导出、删除客户。


三、完整业务协作流程(从定义权限 → 分配 → 登录校验)

阶段1:代码层定义权限(系统初始化)

  1. 在项目PermissionDefinitionProvider中编写所有权限、分组
    // 1. 创建权限分组
    var userGroup = context.AddGroup(AbpIdentityPermissions.GroupName, L("IdentityManagement"));
    // 2. 定义细分权限
    userGroup.AddPermission(AbpIdentityPermissions.Users.Default, L("UserList"));
    userGroup.AddPermission(AbpIdentityPermissions.Users.Create, L("CreateUser"));
    userGroup.AddPermission(AbpIdentityPermissions.Users.Delete, L("DeleteUser"));
    
  2. 应用启动后自动写入AbpPermissionGroups、AbpPermissions两张表,作为权限字典,不能动态新增只能代码定义。
  3. 在应用服务/控制器上加[Authorize("AbpIdentity.Users.Create")]标记,声明接口需要对应权限。

阶段2:后台管理端分配权限(运维操作,写入AbpPermissionGrants)

方式1:给角色分配权限(最常用,批量管理)
  1. 后台创建角色 → 保存到AbpRoles
  2. 打开角色权限弹窗,勾选权限保存
  3. 系统批量插入/更新AbpPermissionGrants,每条记录绑定RoleIdPermissionId
  4. 用户分配角色:在用户页面勾选角色,写入中间表AbpUserRoles
    → 该用户自动继承此角色全部权限
方式2:直接给用户单独授权(个性化特例)
  1. 用户详情页点击「权限」,单独勾选额外权限
  2. 直接写入AbpPermissionGrants,填充UserId
    → 仅当前用户生效,同角色其他用户不受影响
方式3:部门批量授权(组织架构场景)
  1. 创建部门树AbpOrganizationUnits
  2. 给部门绑定角色(写入AbpOrganizationUnitRoles
  3. 用户加入部门(写入AbpUserOrganizationUnits
    → 用户自动继承部门绑定角色的全部权限,适合集团分公司统一权限
方式4:租户全局权限

给整个租户分配通用权限,租户下所有用户默认拥有。

阶段3:用户登录、身份构建(Identity认证流程)

  1. 用户输入账号密码,校验AbpUsers账号、密码哈希、锁定状态;
  2. 登录成功后生成Claims凭证,携带:
    • UserId、TenantId(IAbpSession核心标识)
    • 用户所有角色名称、用户自定义Claims(AbpUserClaims)、角色继承Claims(AbpRoleClaims)
  3. 写入AbpSessions会话表,记录在线登录状态;
  4. OpenIddict签发Token,后续接口请求携带Token完成身份识别。

阶段4:接口访问时权限校验(运行时拦截)

  1. 请求进入带[Authorize(权限Key)]的接口;
  2. ABP IPermissionChecker 自动执行4层权限查询:
    1. 通过IAbpSession获取当前UserId、TenantId
    2. 查租户全局权限、用户所属OU权限、用户绑定角色权限、用户单独权限
    3. 合并所有允许权限集合,校验接口要求的权限是否存在、无拒绝标记
  3. 校验通过:正常执行业务代码;校验失败:直接抛出403无权限异常。

四、关键配套体系协作(Claim、OU、用户委托补充)

1. Claim 身份扩展(AbpUserClaims / AbpRoleClaims)

权限只控制「能不能访问」,Claim控制「身份附加信息」:

  • 角色级Claim:给角色设置Department=销售部,该角色所有用户自动携带该身份;
  • 用户级Claim:单独给用户设置StaffNo=001,用于业务过滤数据(如只能看自己工号数据);
  • 存储在JWT Token中,业务代码可直接读取,不属于权限,但和Identity身份体系绑定。

2. OU组织单元完整联动场景

树形部门 + 部门绑定角色 + 用户多部门归属:

  1. 总公司 → 分公司A → 销售一部(树形OU)
  2. 销售一部绑定角色【销售专员】
  3. 员工张三同时归属销售一部、临时项目组OU
  4. 张三自动获得两个OU绑定角色的全部权限,实现跨部门权限叠加。

3. 用户委托 AbpUserDelegations

ABP独有身份代理功能:

  • 用户A授权用户B在指定时间段代为登录A账号;
  • 登录时IAbpSession区分UserId(代理人B)ImpersonatorUserId(原用户A)
  • 校验权限时使用原用户A的全部权限,代理人仅操作身份隔离,不改变权限判定逻辑。

4. 多租户隔离底层保障

所有Identity核心表(Users/Roles/OU/PermissionGrants)都带TenantId

  • 宿主(Host):TenantId=null,管理所有租户;
  • 租户A:只能查询、操作自己TenantId下的用户/角色/授权;
  • 租户之间角色、权限数据完全隔离,互不干扰。

五、一张图看懂整体流转(极简总结)

代码定义权限(AbpPermissions)
        ↓
后台分配权限 → AbpPermissionGrants(4种授权对象:租户/OU/角色/用户)
        ↓
用户绑定角色(AbpUserRoles) / 用户加入部门(AbpUserOrganizationUnits)
        ↓
用户登录 → 生成身份凭证(携带UserId、TenantId、角色、Claims)
        ↓
访问接口触发[Authorize]校验 → 四层权限合并校验
        ↓
有权限放行 / 无权限返回403

六、开发常用场景对比

场景 实现方案 用到的核心表
统一批量给一类人分配权限 角色授权 AbpRoles + AbpUserRoles + AbpPermissionGrants(RoleId)
单个用户特殊权限,不影响其他人 用户直接授权 AbpPermissionGrants(UserId)
整个部门所有人统一权限 OU绑定角色 AbpOrganizationUnits + AbpOrganizationUnitRoles
租户全部用户默认基础权限 租户全局授权 AbpPermissionGrants(TenantId)
给用户附加业务身份字段(工号、部门编码) Claim声明 AbpUserClaims / AbpRoleClaims
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐