权限管理架构说明与选型建议

一、当前实现概览

  • DataTalk(后端):内置 RBAC(角色权限、用户角色、角色资源范围)、权限码(如 space:viewuser:edit)、资源级控制(空间/仪表盘/图表/数据集/数据源)。支持对接企业 IDP/SSO:认证可切换为本地账号或 SSO Token,通过「第三方角色映射」将 IdP 角色映射到本系统角色。
  • DataView(前端):在「系统设置」下提供 权限管理(角色权限、用户角色、角色资源范围、第三方角色映射)与 用户管理(用户 CRUD、分配角色、状态启用/禁用/封禁)。入口:顶部导航「设置」、空间列表页「权限管理」「用户管理」按钮。

1.1 BI 空间隔离与资源继承关系

  • Space 作为权限隔离单元
    • BI 系统以 space 作为最小隔离边界;
    • 没有某个 space 的访问权限时,该 space 下关联的 dashboardpaneldataset 等资源一律不可见、不可访问。
  • 仪表盘与图表(Panel)从属关系
    • dashboard 归属某个 space
    • 没有当前 dashboard 的访问权限时,其下关联的所有 panel 也均无权限访问(不展示、不允许通过直链访问)。
    • 在实现上,panel 的鉴权需同时满足所属 space 和所属 dashboard 的权限校验。

二、是否把权限管理单独做一个项目?(数据可视化与权限分割)

2.1 拆成独立项目的潜在好处

说明
职责清晰 权限服务只负责认证/授权,数据可视化只负责看板与报表,边界清楚。
多端复用 同一套权限服务可被 DataView、其他前端、API 网关、第三方系统共用。
独立演进 权限模型升级、对接第三方 IDP/权限中心时,可单独发布,不绑死在可视化项目里。
团队分工 权限团队与业务团队可并行开发、独立部署与扩缩容。

2.2 拆成独立项目的成本与风险

说明
运维与部署 多一个服务:部署、监控、网络、版本兼容都要管。
时延与依赖 每次鉴权多一次网络调用,权限服务故障会直接影响所有依赖方。
数据与事务 用户/角色/权限若要与业务数据强一致或做联合查询,跨服务事务与数据同步更复杂。
当前规模 若仅 DataView + DataTalk 使用,拆成独立项目收益有限,复杂度反而上升。

2.3 建议

  • 现阶段不拆。权限逻辑继续放在 DataTalk 内,通过模块(如 RbacModule)与 API(/rbac/*/users/*)清晰封装即可。这样:
    • 部署简单,无额外服务;
    • 鉴权在应用内完成,延迟低、无额外网络故障点;
    • 用户/角色与业务资源在同一数据源,便于事务与查询。
  • 何时考虑拆:当出现以下情况时再考虑独立权限服务或独立项目:
    • 多个前端/多套系统要共用同一套用户与权限;
    • 需要统一对接企业 IDP/SSO/权限中台;
    • 权限模型或合规要求明显变复杂,需要独立团队与发布节奏。

三、是否接入第三方权限系统?

3.1 不接入(使用内置权限)

  • 适用:单系统或少量系统、权限模型固定、无强合规或企业统一身份要求。
  • 优点:实现简单、无外部依赖、数据与流程完全自控。
  • 缺点:与企内其他系统账号/权限不统一,多系统时需各自维护。

3.2 接入第三方(企业 IDP / 权限中台 / IAM)

  • 适用:多系统统一登录、统一权限、审计与合规要求高。
  • 典型形态
    • 仅认证:第三方只做登录(OAuth2/OIDC),登录后由 DataTalk 自己的 RBAC 做授权(角色、权限、资源范围)。
    • 认证 + 授权:第三方提供用户、角色、权限、资源等,DataTalk 通过接口或同步数据做鉴权,或仅做代理转发。

3.3 建议与预留方式

  1. 短期:继续使用 内置 RBAC,满足 DataView + DataTalk 的权限与用户管理即可。
  2. 预留对接能力(便于将来接入第三方):
    • 认证层
      • 在 DataTalk 中抽象「登录/校验 token」接口(如 AuthProvider),当前实现为本地用户名密码 + JWT,后续可增加 OAuth2/OIDC 等实现,而不改业务代码。
    • 用户/角色来源
      • 若未来第三方只提供「谁登录了」,仍由 DataTalk 维护「角色/权限/资源范围」:在登录回调里用第三方返回的用户标识在本地做「用户匹配/创建」和「角色绑定」即可。
    • 若第三方也管权限
      • 可增加「权限数据同步」或「鉴权代理」:例如定时同步角色/权限,或在需要鉴权时调用第三方 API,再由 DataTalk 统一对外提供 user:viewspace:edit 等语义。当前内置 RBAC 的权限码与资源类型设计(如 resourceType + resourceId)便于与外部模型做映射。
  3. 不推荐:在尚未有明确第三方方案前,就拆出独立「权限项目」并强依赖外部系统;建议先保持内置、接口可插拔,等有明确接入需求再拆或再接。

四、总结

问题 建议
权限管理是否单独做一个项目? 当前不必。继续内置于 DataTalk,以模块与 API 形式封装;等多系统/多租户/统一身份需求明确后再考虑独立服务。
是否接入第三方权限? 可选。不接入则用内置 RBAC;若接入,建议在 认证层用户/角色来源 做抽象与适配,权限码与资源模型保持可映射,便于对接。
如何继续完善? 见下节:保证设置入口可见、权限/用户页面完整、后端 API 与前端鉴权一致,并预留认证/授权扩展点。

五、SSO/第三方权限对接(已实现)

  • 认证策略
    • 本地(AUTH_MODE=local)POST /auth/login 使用账号密码,通过 LocalAuthStrategy 校验,签发本系统 JWT。
    • SSO(对接企业 IdP)POST /auth/sso/login 请求体 { accessToken: string },使用 SsoAuthStrategy 校验 IdP 颁发的 JWT(需配置 SSO_JWT_SECRET 或后续扩展 JWKS),解析出 sub/name/email/roles,再与本系统用户关联并同步映射角色。
  • 用户关联
    • 通过 user.external_id(对应 IdP 的 sub)或 user.email 解析已有用户;若不存在则自动创建本地用户(auth_source=sso),不暴露密码。
  • 角色映射
    • external_role_mappingexternal_role_code(第三方角色/组标识)→ local_role_id(本系统角色)。
    • SSO 登录时:根据 token 中的角色列表查映射,将对应本系统角色写入 user_role,此后权限与本地 RBAC 一致。
  • 配置
    • .env / .env.exampleAUTH_MODESSO_JWT_SECRETSSO_ROLES_CLAIM(如 rolesrealm_access.roles)。
  • 前端
    • 权限管理页增加「第三方角色映射」Tab:维护外部角色标识 → 本系统角色的映射。
    • 嵌入企业系统时:由宿主应用取得 IdP token,调用 POST /auth/sso/login 传入 accessToken,拿到本系统 JWT 后访问 DataView。

这样既可独立部署(本地账号 + 本系统权限),也可以 SaaS/PaaS 嵌入(企业 IdP 登录 + 映射对接本系统资源与权限)。


六、本仓库已做的完善(与后续可做)

  • 前端
    • 提供统一的 系统设置 入口(顶部导航「设置」),并在此下提供 权限管理(含第三方角色映射)、用户管理 子页。
    • 设置采用布局页 + 子路由(如 /settings/settings/permission/settings/users),便于后续增加更多设置项。
    • 权限/用户管理页面已存在且可用;无 user:view 的用户不显示「设置」入口,访问设置相关路由会被鉴权拦截。
  • 后端
    • 已有完整 RBAC、用户 CRUD、登录返回角色与权限与资源范围;资源操作(含禁用)与权限码一致。
    • 已实现认证策略抽象(LocalAuthStrategySsoAuthStrategy)、SSO 登录接口、第三方角色映射表与 API、SSO 登录时自动同步映射角色。
  • 后续可做
    • 若 IdP 使用 RS256:在 SsoAuthStrategy 中增加 JWKS 拉取与校验。
    • 前端在「嵌入模式」下:检测到宿主传入的 token 时自动调用 POST /auth/sso/login 完成静默登录。