微服务体系用户权限方案设计

Posted by 高强 on April 5, 2022

概述

基于 RBAC 角色权限设计,前后端各自管理权限字典

  • 菜单及权限对应UI级别的按钮显示与隐藏由前端控制
  • 后端以权限码映射到具体的接口权限
  • 权限码列表在登录接口中根据当前用户的角色,仅返回当前用户对应角色所具有的权限(即用户所在角色不具备的权限不在接口返回)
  • 用户权限发生变更时处理方案
    1. 直接将用户当前的登录 token 过期,用户需要重新登录
    2. 通过 websocket 等手段下发变更权限
      • 目前简单处理选用方案 1
  • 后端返回 http 状态码 401 的情况:token 过期、token 格式错误
  • 后端返回 http 状态码 403 的情况:用户角色权限不足

权限码定义

权限码按后端接口逻辑定义,示例:Report.R

CURD

  • C = Create
  • U = Update
  • R = Retrieve
  • D = Delete

自定义

  • I = Import
  • E = Export
  • S = Sync

接口示例

登录接口

{    
    "roleId": "60d437f7d548b939f9ab70d7",
    "roleName": "管理员",
    // 返回用户当前所在角色中所拥有的权限id列表
    "pmIds": ["60d437f7d548b939f9ab70d7", "60d437f7d548b939f9ab70d1", "60d437f7d548b939f9ab70d3", "60d437f7d548b939f9ab70d5"]
}

特殊处理

系统预置角色

  • 系统预置角色包含:管理员、普通员工等
  • 对于预置角色:无法删改其内容,无法修改其权限
  • 如果用户当前角色为自定义角色,该角色被删除后,用户角色默认变更为【普通员工】预置角色

数据权限

上述权限方案仅限于处理前端按钮及后端接口访问粒度,对于某些场景下,需要对用户的可访问数据范围做限制时,应在角色外再定义一层用户数据权限。
比如,用户具有项目列表接口访问权限,但在数据上进允许用户访问某些地区的项目,那应该基于功能权限外,再给用户定义可访问的数据范围,并在逻辑实现处做拦截处理。

在微服务场景下的适配

上述权限方案对应的每个接口需要处理接口与权限码的映射关系,在标准的 SpringBoot 项目架构下,可以使用权限码注解等方式实现。在微服务场景下,可使用的映射方案为:

  1. 在网关层配置接口 - 权限码映射关系,接口可由地址+请求方法唯一确定

    请求到达网关时即可根据地址+请求方式,判断用户是否具备该接口访问权限

  2. 设计BFF层,将该层当做标准单体架构,权限拦截在BFF层完成

    可以根据不同的BFF层灵活设计拦截方案,包括白名单放通等