权限管理架构说明与选型建议
一、当前实现概览
- DataTalk(后端):内置 RBAC(角色权限、用户角色、角色资源范围)、权限码(如
space:view、user:edit)、资源级控制(空间/仪表盘/图表/数据集/数据源)。支持对接企业 IDP/SSO:认证可切换为本地账号或 SSO Token,通过「第三方角色映射」将 IdP 角色映射到本系统角色。
- DataView(前端):在「系统设置」下提供 权限管理(角色权限、用户角色、角色资源范围、第三方角色映射)与 用户管理(用户 CRUD、分配角色、状态启用/禁用/封禁)。入口:顶部导航「设置」、空间列表页「权限管理」「用户管理」按钮。
1.1 BI 空间隔离与资源继承关系
- Space 作为权限隔离单元:
- BI 系统以
space 作为最小隔离边界;
- 没有某个 space 的访问权限时,该 space 下关联的
dashboard、panel、dataset 等资源一律不可见、不可访问。
- 仪表盘与图表(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 建议与预留方式
- 短期:继续使用 内置 RBAC,满足 DataView + DataTalk 的权限与用户管理即可。
- 预留对接能力(便于将来接入第三方):
- 认证层:
- 在 DataTalk 中抽象「登录/校验 token」接口(如
AuthProvider),当前实现为本地用户名密码 + JWT,后续可增加 OAuth2/OIDC 等实现,而不改业务代码。
- 用户/角色来源:
- 若未来第三方只提供「谁登录了」,仍由 DataTalk 维护「角色/权限/资源范围」:在登录回调里用第三方返回的用户标识在本地做「用户匹配/创建」和「角色绑定」即可。
- 若第三方也管权限:
- 可增加「权限数据同步」或「鉴权代理」:例如定时同步角色/权限,或在需要鉴权时调用第三方 API,再由 DataTalk 统一对外提供
user:view、space:edit 等语义。当前内置 RBAC 的权限码与资源类型设计(如 resourceType + resourceId)便于与外部模型做映射。
- 不推荐:在尚未有明确第三方方案前,就拆出独立「权限项目」并强依赖外部系统;建议先保持内置、接口可插拔,等有明确接入需求再拆或再接。
四、总结
| 问题 |
建议 |
| 权限管理是否单独做一个项目? |
当前不必。继续内置于 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_mapping:external_role_code(第三方角色/组标识)→ local_role_id(本系统角色)。
- SSO 登录时:根据 token 中的角色列表查映射,将对应本系统角色写入
user_role,此后权限与本地 RBAC 一致。
- 配置
.env / .env.example:AUTH_MODE、SSO_JWT_SECRET、SSO_ROLES_CLAIM(如 roles 或 realm_access.roles)。
- 前端
- 权限管理页增加「第三方角色映射」Tab:维护外部角色标识 → 本系统角色的映射。
- 嵌入企业系统时:由宿主应用取得 IdP token,调用
POST /auth/sso/login 传入 accessToken,拿到本系统 JWT 后访问 DataView。
这样既可独立部署(本地账号 + 本系统权限),也可以 SaaS/PaaS 嵌入(企业 IdP 登录 + 映射对接本系统资源与权限)。
六、本仓库已做的完善(与后续可做)
- 前端
- 提供统一的 系统设置 入口(顶部导航「设置」),并在此下提供 权限管理(含第三方角色映射)、用户管理 子页。
- 设置采用布局页 + 子路由(如
/settings、/settings/permission、/settings/users),便于后续增加更多设置项。
- 权限/用户管理页面已存在且可用;无
user:view 的用户不显示「设置」入口,访问设置相关路由会被鉴权拦截。
- 后端
- 已有完整 RBAC、用户 CRUD、登录返回角色与权限与资源范围;资源操作(含禁用)与权限码一致。
- 已实现认证策略抽象(
LocalAuthStrategy、SsoAuthStrategy)、SSO 登录接口、第三方角色映射表与 API、SSO 登录时自动同步映射角色。
- 后续可做
- 若 IdP 使用 RS256:在
SsoAuthStrategy 中增加 JWKS 拉取与校验。
- 前端在「嵌入模式」下:检测到宿主传入的 token 时自动调用
POST /auth/sso/login 完成静默登录。