🌐 语言: 中文版 | English Version
摘要:登录用户承载认证,业务用户承载业务关系。是否拆分取决于业务主体是否需要独立存在,是否引入租户则取决于服务与管理边界。
前面讨论企业统一身份治理时,重点是让多个业务系统共用认证与身份管理能力。认证入口统一之后,还有一个模型问题:同一个登录账号,在业务里是否始终代表同一个参与主体?
很多企业系统最初只有一种“用户”:登录用它,业务记录引用它,权限也配置在它上面。在一人对应一套业务关系时,这个模型很直接。
但同一个人可能参与几项相互独立的业务。同一套登录凭证之下,他在不同业务中的资格、关系和责任并不相同。如果仍然只用一个用户对象承载这些含义,业务差异就会不断变成这个对象上的附加条件。
这时值得重新考虑的,是登录用户与业务用户是否应该分开,以及这种拆分为什么不一定需要引入多租户。
多个业务账号的背景
在企业业务中,同一个人可能同时拥有几份独立的任职或合作关系。例如,一名员工在集团内两家公司承担采购职责,使用同一个登录账号,但两边的任职资格、授权范围和有效期分别管理。结束其中一份任职,不应影响另一份,也不必注销登录账号。
这里的多个业务账号,指的就是这些需要独立管理的业务参与身份,本文称为“业务用户”。它们各自承载资格、关系和历史记录,认证仍然可以共用一套登录凭证。
如果差异只是操作权限,带作用范围的角色可能已经足够;当参与关系本身需要独立存在和结束时,才有必要单独表达业务用户。同一个人使用多个应用,并不自动意味着需要多个业务用户。前面网关层 Per-Client 鉴权隔离讨论的是应用访问边界,这里关注的是业务关系的主体。
同一个“用户”,承担了两种职责
登录用户首先表达一个认证主体:系统通过它确认访问者使用的是哪个账号。
业务用户表达的是这个账号在某项业务中的参与身份。业务关心的除了能否登录,还有是否具备参与资格、处于什么业务状态,以及操作应当归属于谁。
两者经常同时出现,因此很容易被当成同一个对象。但它们的变化原因并不相同。
例如,一个人不再参与某项业务,并不意味着他的登录账号也应当失效。如果他仍在参与其他业务,认证能力就需要继续保留。反过来,认证通过也不能直接说明他具备每一项业务的参与资格。
当这些区别开始影响日常业务时,“用户”就不再只是一个方便的统一称呼,而是两个需要分别表达的概念。
拆开的目的,是让关系有明确归属
这里讨论的模型很简单:一个登录用户,可以关联多个业务用户。
flowchart TD
L[登录用户
认证主体] --> A[业务用户 A
一组业务关系]
L --> B[业务用户 B
另一组业务关系]
图中的 A、B 只表示两份独立的业务身份,不预设它们属于不同应用、组织或租户。
登录用户保留认证层面的含义;业务中的资格、状态和关系,由相应的业务用户承载。这样,同一个人可以继续使用一个登录账号,而不必把几份业务关系合并成一份。
这也解释了为什么仅仅增加角色,有时还不够。
在把权限从菜单里拆出来一文中,角色负责组织权限。这里仍然保留这个职责:如果差异只是“能做哪些操作”,在同一个用户上配置不同角色可能已经足够。但如果需要分别记录任职、合作资格和行为归属,还需要明确这些权限附着在哪个业务主体上。
是否拆分,取决于业务身份是否需要独立存在。角色仍然可以配置在业务用户上,继续表达它的权限;两者承担不同的职责。
为什么不直接按多租户来设计
看到一个人有多份业务身份,很容易想到:给每份身份增加一个租户,不就能区分了吗?
这种设计能否成立,要先看“租户”在系统里代表什么。
多租户通常用于表达多个客户或用户群体使用同一套服务时的边界。它会进一步牵涉数据归属、管理范围和资源共享等问题。租户也可以对应企业内部的业务单元,并不只用于对外 SaaS。Microsoft 的多租户架构说明也明确区分了租户与用户。
登录用户与业务用户的拆分,关注的则是一个账号对应哪些业务主体。
| 模型 | 首先需要回答的问题 |
|---|---|
| 登录用户 | 访问者通过哪个账号完成认证? |
| 业务用户 | 这项业务中的资格、关系和责任归属于谁? |
| 租户 | 哪些用户与资源属于同一个服务或管理边界? |
如果几份业务身份确实分别属于独立租户,那么按租户组织它们是自然的。但如果差异只发生在业务参与身份上,并没有相应的租户边界,为此引入租户就会增加一层需要解释的含义。
例如,同一个服务范围内,一个人可能拥有两份不同的业务身份。把它们解释为两个租户以后,还要继续回答:为什么这两个租户共享业务资源?它们是否需要各自的管理范围?哪些关系允许跨租户存在?
这些问题未必是原本的需求,却会进入后续设计。
因此,在没有独立租户边界的前提下,先拆开登录用户和业务用户,更接近需要表达的问题。它只增加一个有明确用途的业务主体,而不把所有身份差异都解释成租户差异。
两种模型可以同时成立
登录用户与业务用户的拆分,并不排斥多租户。
如果系统本身服务于多个独立租户,一个登录用户可以关联不同租户中的业务用户。认证身份与租户内的业务身份仍然可以分开。
有些系统中,一条“用户与租户的成员关系”就足以承载业务身份;另一些系统中,业务用户还需要独立的状态与关系。具体用什么名字、是否单独成为一个实体,取决于它需要表达的业务含义。
多租户也不必意味着每个租户都维护一套独立登录凭证。因此,选择拆分用户模型的理由,不应建立在“多租户一定要重复注册”这样的假设上。
更有用的判断顺序是:先确认业务主体,再确认租户边界。如果两者恰好重合,可以让模型保持简洁;如果不重合,也不必强行把它们压成同一个概念。
拆分模型时,如何保留存量业务关系
在已有 IAM 接入体系中,用户 ID 往往已经被业务系统用于关联权限、业务记录和历史操作。拆分用户模型时,如果同时给所有业务用户重新编号,就需要连同这些关系一起迁移。
当存量用户原本只有一份业务身份时,一种兼容取舍是:让承接原有业务关系的业务用户沿用原用户 ID,新增的业务身份再使用独立的 ID。这样,原有业务记录可以继续引用同一个标识,既有接入系统也能减少关联数据和读取标识方式的改动。
这里保留的是标识的连续性。即使登录用户与某个业务用户的 ID 数值相同,它们仍然是两个职责不同的对象;这种同号关系是存量迁移的兼容安排,不宜成为新业务逻辑的依赖。
当大部分用户仍然只有一份业务身份时,这个选择尤其有价值:模型能够表达新增的多身份需求,原有接入也不必因此全面重编用户标识。但是否兼容,仍要核对接入系统实际使用的身份语义、权限判断和数据范围。保留 ID 可以减少迁移范围,不能单凭这一点认定所有接入都不受影响。
拆分之后,复杂性去了哪里
拆开模型的收益,是变化可以落在它所属的对象上。某份业务资格结束,只影响相应的业务用户;登录账号的认证状态,则有自己的含义。历史业务记录也可以继续指向当时的业务主体。
代价是,系统不能再用一个含糊的“用户”指代所有场景。业务操作需要明确使用哪一个业务用户,记录行为时也需要分清登录主体与业务主体。
这增加了模型理解与关系维护的成本。模型拆分本身也不会自动完成权限隔离,授权仍需以实际业务主体和业务规则为依据。
所以,并不是所有系统都值得这样拆。如果一个登录用户始终只对应一个业务主体,业务差异也都能通过角色表达,保持简单模型可能更合适。
只有当业务关系确实需要独立存在时,这层拆分才是在表达已有复杂性,而不是提前制造复杂性。
从职责出发决定模型
用户模型很容易随着功能增长而扩展:多一个状态、多一组角色、多一个所属范围。每次增加都能解决眼前的问题,但也可能让“用户”逐渐承担几种不同的含义。
我更倾向于在这些含义开始独立变化时,重新检查对象的职责。认证需要一个稳定的登录主体,业务需要能够表达自身关系的参与主体,两者有关联,也可以有各自的生命周期。
租户是否需要进入模型,则由服务和管理边界决定。先说明白为什么需要一个对象,再决定它与其他对象如何关联,模型才不容易被某个熟悉的架构名称带着走。