林加入星河科技
假设本站已有账号:陈(U1)和林(U2)。这是一组虚构的设计示例,ID 是阅读用别名,生产设计使用 UUIDv7。
随后陈创建研发部 O1 并安排林加入;林在 E1 有业务组织后,默认归属自动移除。若林此前的主组织指向 O0,该选择先被清空;林可自行选 O1。平台操作员另建跨企业用户组 G1 并任命组管理员,组管理员将林加入。组关系与企业成员资格相互独立。
从一封邀请出发,理解企业、成员、组织、用户组和授权如何协作;同时审视设计距离真实可用还有多远。
account 管理“谁属于哪个企业、组织和用户组,以及在这些范围里有什么管理权”。用户账号与登录身份由 auth 管理;平台操作员及应用分配由 management 管理。
deploy/local/mysql/stubs/30-account.sql 只是本地/测试契约桩,仅含企业、组织、组、审计四张简化表和种子数据;不能用它证明真实业务可运行。管理账号、登录、会话与验证结果;account 读取其发布的视图。
管理企业成员、组织、邀请、角色、组、云绑定及本应用审计。
管理操作员与应用分配;按已知 ID 读取 account 的组织、组视图。
先成为企业成员才能归属该企业组织;没有业务组织时自动归入默认组织。
组织属于企业并可有层级;用户组是本站集合,可跨企业,管理权独立。
创始人是企业治理身份;角色是单独授予并带具体范围的权限事实。
组织层级只表达结构,不继承管理权限。主组织是账号跨企业的单一选择,可为空;只有当前有效组织归属可被选中。
假设本站已有账号:陈(U1)和林(U2)。这是一组虚构的设计示例,ID 是阅读用别名,生产设计使用 UUIDv7。
随后陈创建研发部 O1 并安排林加入;林在 E1 有业务组织后,默认归属自动移除。若林此前的主组织指向 O0,该选择先被清空;林可自行选 O1。平台操作员另建跨企业用户组 G1 并任命组管理员,组管理员将林加入。组关系与企业成员资格相互独立。
以下为同一时点的设计示例快照:林已接受邀请并进入研发部。为可读性只展示关键列;T0 为 2026-11-01 09:00,T1 为 11-02 10:00,T2 为 11-03 10:00(UTC);H、D、C 为摘要/密文占位符,非可用凭据。省略的时间戳和摘要列仍须遵循设计。表之间的别名是引用,不是实际 SQL 值。
| 设计表 | 示例行(关键列) | 约束与含义 |
|---|---|---|
account_enterprise | id=E1 · name=星河科技 · founder_id=U1 · create_operation_id=OP0 · create_request_hash=H0 | 企业 ID 主键;创始人 + 开通请求键唯一。 |
account_enterprise_member | (E1,U1,T0) (E1,U2,T1) | 复合主键 (enterprise_id, account_id);移除后当前关系物理删除。 |
account_organization | (O0,E1,默认组织,NULL,true,E1) (O1,E1,研发部,NULL,false,NULL) | 列依次为 id、enterprise_id、name、parent_id、is_default、default_enterprise_id;每企业至多一个默认组织。 |
account_organization_member | (E1,O0,U1,T0) (E1,O1,U2,T2) | 列为 enterprise_id、organization_id、account_id、joined_at;林有业务归属,故不再属于 O0。 |
account_primary_organization | (U1,O0,T0) (U2,O1,T2) | 列为 account_id、organization_id、updated_at;只能指向本人现有归属。 |
| 设计表 | 示例行(关键列) | 约束与含义 |
|---|---|---|
account_invitation | id=I1 · enterprise_id=E1 · normalized_email=lin@example.com · inviter_id=U1 · proposed_role=enterprise_admin · status=accepted · token_version=1 · token_digest=D1 · accepted_account_id=U2 · accept_operation_id=OP1 · accept_request_hash=H1 · accepted_at=T1 | 过期由时间计算;接受的账号、键、摘要和时间共同保存。令牌明文不入表。 |
account_verification_request | id=VR1 · purpose=invitation_accept · subject_id=U2 · operation_id=OP1 · method=email · normalized_target=lin@example.com · invitation_id=I1 · owner_type=NULL · owner_id=NULL · created_at=2026-11-02 09:55 · expires_at=2026-11-02 10:25 | 这是验证委托,不是验证结果;结果由 auth 持有。示例假定尚未被清理。 |
account_role_grant | (R1,U2,enterprise_admin,enterprise,E1,T1) (R2,U1,group_admin,group,G1,T2) | 列为 id、account_id、role_code、scope_type、scope_id、granted_at;范围配对受约束。 |
| 设计表 | 示例行(关键列) | 约束与含义 |
|---|---|---|
account_user_group | id=G1 · name=试用成员 · description=NULL · created_at=T2 | 组不属于企业;操作员登记,组管理员另行授予。 |
account_group_member | (G1,U2,T2) | 列为 group_id、account_id、joined_at;移除企业成员不会自动删除组关系。 |
account_external_binding | owner_type=enterprise · owner_id=E1 · provider=huawei · external_domain=huawei-cn · external_account_id=HC1 · operation_id=OP2 · request_hash=H2 · verification_id=V2 · created_at=T2 | 假设该站能力已验收并开启;同一所有者至多一个绑定,同一云账号可被多个所有者绑定。 |
account_audit_event | event_id=A1 · event_version=1 · occurred_at=T1 · category=user · actor_type=user · actor_id=U2 · action=invitation.accept · target_type=invitation · target_id=I1 · enterprise_id=E1 · outcome=success · policy_version=p2 · policy_matches=[] · details={} | 发生时核实企业归属;记录历史,不依赖业务对象当前存在。其他可空字段此例为 NULL。 |
上表展示业务关键列,不是完整 DDL 或可直接执行的 INSERT。设计还包含索引、事务、保留和保护规则;完整字段请参阅文末各 DATA 文档。桩 SQL 的结构与这份设计并不完全一致。
文档对并发、授权和恢复的设计相当细,但“写了规则”距离“产品场景可交付”还有明显距离。以下区分未实现、未定方案和明确不在首期的边界。
优先级为本次专业评估,不是仓库既定排期。首期排除的能力是产品选择,但一旦目标客户需要相应场景,就构成实际缺口。
推荐业务表述:“企业身份提供商联合登录(企业 SSO)”。企业配置自己的 IdP;受邀员工使用企业身份登录平台,平台完成身份映射后,根据企业成员资格与角色授权。
需要明确:企业 IdP 如何与企业绑定和发现;采用 OIDC 还是 SAML;使用发行方 + 稳定主体标识映射,还是允许经验证邮箱参与首次关联;邀请邮箱与 IdP 身份不匹配时如何处理;停用、离职、会话撤销和 IdP 不可用时如何处置。不能仅凭相同邮箱静默合并账号,也不能把认证成功当成企业授权成功。自动建账号或自动加企业(JIT provisioning)是另一个明确的产品决策。
把问题分成三层:本项目已有的资产、可直接接入的协议与库,以及可选的完整身份产品。以下覆盖主要技术类别与典型选项,不声称穷尽所有厂商。能复用组件不等于本项目已经支持企业 SSO。
| 资产 | 可复用什么 | 事实与仍需补充 |
|---|---|---|
| management 的 OIDC 客户端 | OperatorIdpClient 中基于 Spring Security 的授权码、PKCE、发现、令牌兑换、验签;参考 iss + sub 身份键与失败处理。 | 已有操作员平面代码和契约;客户企业登录要另做企业连接配置、路由、映射和治理,不能共用操作员身份与回调。真实华为 IdP 验收仍有未满足项。 |
| Spring Security OAuth2 Client / JOSE | 授权请求、OIDC ID Token 验证与协议工具;management 已有依赖。 | 用户平面需独立接入和验证;库不替你决定谁可加入企业。 |
| Spring Session / 本地会话模式 | 参考操作员登录保存 state、nonce、PKCE verifier 和本地会话的做法。 | 用户会话归 auth;不要复用操作员会话或 Cookie。auth 的用户平面设计未实现。 |
| auth 身份、关联、验证与会话设计 | 复用既有概念边界、稳定主体映射、验证与会话设计。 | 当前是设计,并非现成用户 SSO 实现;须扩展企业 IdP 类型与连接范围。 |
| account 邀请、成员、角色与审计设计 | 复用受邀加入企业、角色范围和事务/审计规则。 | account 尚未构建;企业 SSO 的登录认证与邀请接受仍需显式衔接。 |
| management 应用分配与协议组件 | 可复用下游应用分配概念及 Spring Authorization Server 相关技术,构建平台对下游应用的身份提供能力。 | 这是平台作为下游 IdP 的方向,不直接实现平台登录上游企业 IdP;auth 协议实现和端到端待验收。 |
| 已有第三方身份渠道设计 | JustAuth、WxJava 等渠道适配、短期 state、验证结果与故障边界可作参考。 | 现有规格面向列出的社交渠道;不能假定天然具备多企业 IdP 配置或 SAML。 |
| mock IdP 与测试方法 | 参考项目中的 mock-oauth2-server、错误 state/nonce/issuer 等验收思路。 | 覆盖模拟、并发和异常后,还需对选定客户真实 IdP 做互操作验收。 |
| 技术 | 用来解决什么 | 适用与边界 |
|---|---|---|
| OpenID Connect(OIDC) | 基于 OAuth 2.0 的用户认证;企业 IdP 为 OP,平台为 RP / Client。 | 首选评估授权码 + PKCE;验证签名、issuer、audience、时间、nonce、state 等。OAuth 本身的访问授权不等于用户认证。 |
| SAML 2.0 Web SSO | 企业 IdP 向平台 SP 发送签名断言,适配大量现有企业系统。 | 要实现元数据、证书轮换、断言签名/受众/时效/关联校验;明确 SP 发起及是否支持 IdP 发起。 |
| SCIM 2.0 | 跨域创建、更新、停用用户及组等目录数据。 | 可选的入离职自动化,不是登录协议;租户隔离、鉴权、冲突和撤权语义仍需产品设计。 |
| LDAP / Active Directory | 企业目录与用户数据源;可由身份代理连接。 | 不是浏览器联合登录协议;直连需要网络、TLS、凭据与目录运维,通常由企业 IdP 包装为 OIDC/SAML。 |
| WebAuthn / Passkeys、MFA | 用户认证方式或强度,可由企业 IdP 提供。 | 不是平台与 IdP 的联合协议;若平台要求 MFA,须约定可信的认证强度声明及缺失时行为。 |
| OIDC Discovery / JWKS、SAML Metadata | 发现端点和公钥、交换信任元数据。 | 需校验可信 issuer / entity、限定网络访问并处理密钥与证书轮换;不能信任任意用户输入的元数据地址。 |
| 类型与例子 | 可以复用 | 取舍 |
|---|---|---|
| Spring Security OAuth2 Client / JOSE | OIDC 客户端、发现、令牌交换与验证。 | 与当前 Java / Spring 最贴合;企业连接、账号关联、租户边界需自行设计。 |
| Spring Security SAML2 Service Provider / OpenSAML | SAML 登录、断言处理及相关协议能力。 | 按实际 Spring 版本验证支持;多企业配置、证书与声明映射仍需建设。 |
| Keycloak、Authentik | 自托管身份代理,接入上游 IdP,向平台提供统一身份入口。 | 可减少协议适配,但新增服务、运维、配置和安全责任;企业成员与权限仍归平台。 |
| Auth0、WorkOS、Stytch 等托管身份服务 | 企业 SSO、身份连接和部分供应商提供的目录同步等能力。 | 能力、地区、数据驻留、价格、授权和协议细节依产品及套餐核验;需评估厂商依赖与跨境要求。 |
| Microsoft Entra ID、Okta、Google Workspace、Ping Identity 等 | 客户侧企业 IdP / 目录,可作为上游身份来源。 | 并非默认替代本平台治理;逐一确认目标客户开放的 OIDC / SAML / SCIM 和声明契约。 |
| Spring Authorization Server | 平台向下游应用提供 OAuth/OIDC 能力。 | 解决下游授权服务器问题;上游企业登录仍需 OIDC 客户端或 SAML SP。 |
建议在产品、接口、代码和验收中统一以下术语。标记“现有设计”的概念不代表已经上线;“建议新增”表示支持企业 SSO 需要明确建模。
| 统一名称 | 英文 / 常见缩写 | 定义与区别 | 状态 |
|---|---|---|---|
| 身份域 / 站点 | Identity domain / site | 账号、配置与策略适用的边界;中国站与国际站分别治理。 | 现有设计 |
| 企业 | Enterprise | 客户治理主体;拥有创始人、成员与组织。是否等同技术租户须另定。 | 现有设计 |
| 租户 | Tenant | 配置、数据或隔离边界;不应未经决策直接等同企业、站点或 IdP 租户。 | 建议澄清 |
| 平台账号 | Platform account / user account | auth 内的本站账号;同一账号可有多个登录身份及企业成员资格。 | 现有设计 |
| 企业成员资格 | Enterprise membership | 账号与企业的有效关系;认证成功不等于已成为成员。 | 现有设计 |
| 创始人 | Founder | 企业开通时确立的治理身份,不等同可委派管理员角色。 | 现有设计 |
| 邀请 | Invitation | 针对指定邮箱、企业和可选角色的加入要约;有有效期、令牌版本和状态。 | 现有设计 |
| 身份提供商 | Identity Provider / IdP | 负责认证用户并向信赖方提供可验证的身份信息。 | 建议新增客户企业语义 |
| 企业身份提供商 | Enterprise IdP | 客户企业选定用于员工认证的 IdP;与平台工作人员使用的操作员 IdP 分开。 | 建议新增 |
| 信赖方 / 服务提供商 | Relying Party (RP) / Service Provider (SP) | 依赖 IdP 认证结果的一方;平台使用 OIDC 时为 RP,使用 SAML 时为 SP。 | 协议角色 |
| 企业身份连接 | Enterprise identity connection | 平台保存的企业与上游 IdP 的信任、协议、配置及状态;一企一连接或多连接待定。 | 建议新增 |
| 身份联合 / 企业单点登录 | Identity federation / Enterprise SSO | 平台信赖外部企业 IdP 的认证;SSO 描述用户体验,联合描述信任关系。 | 建议新增 |
| 身份提供商发现 | IdP discovery / home realm discovery | 确定本次登录应走哪个企业连接;邮箱域名仅是路由线索,归属须验证。 | 建议新增 |
| 已验证域名 | Verified domain | 证明企业控制某邮箱域或域名的事实,可用于路由;不能单独证明某人拥有某账号。 | 建议新增 |
| 外部主体 | External subject | IdP 标识的用户;OIDC 通常以可信 issuer + 原始 sub 标识,SAML 须约定稳定标识与作用域。 | 建议新增 |
| 登录身份关联 | Identity link | 外部主体与平台账号的关系;首次建立与变更需可信证明,不凭同邮箱静默合并。 | 现有概念,企业场景待扩展 |
| 声明 / 断言 | Claim / assertion | IdP 给出的身份或认证信息;必须经协议验证,且各字段可信度由连接契约约定。 | 协议事实 |
| 身份映射 | Identity mapping | 把已验证外部主体映射到平台账号;与把账号加入企业分属不同决定。 | 建议新增 |
| 首次登录自动开通 | Just-in-time provisioning / JIT | 首次成功联合登录时自动建立账号或成员关系;两者是否自动化需分别明确。 | 待决 |
| 账号供给与撤销 | Provisioning / deprovisioning | 创建、更新、停用用户与相关关系的生命周期;SCIM 是可选技术通道。 | 待决 |
| 认证 | Authentication / AuthN | 确认当前主体是谁及认证强度;由 IdP 和平台协议校验共同完成。 | 现有概念 |
| 授权 | Authorization / AuthZ | 判断某账号在指定企业、组织、组或应用上能做什么;不能由登录成功推导。 | 现有设计 |
| 角色授予 | Role grant | 将固定角色授予账号并限定具体企业、组织或用户组范围。 | 现有设计 |
| 组织 / 组织归属 | Organization / affiliation | 企业内结构及账号归属;组织层级不自动继承管理权。 | 现有设计 |
| 用户组 / 组成员 | User group / group membership | 本站范围的独立账号集合,可跨企业;与企业成员和目录组不自动等同。 | 现有设计 |
| 平台会话 | Platform session | 平台认证后建立的本地登录状态;与 IdP 会话的期限和退出行为不同。 | 现有设计 |
| 单点退出 | Single logout / SLO | 协调多个会话退出的能力;是否支持及失败时效果需单独定义。 | 待决 |
| 企业 SSO 策略 | Enterprise SSO policy | 规定允许的登录连接、是否强制 SSO、例外和紧急恢复;多企业账号冲突需决策。 | 建议新增 |
| 审计事件 | Audit event | 记录主体、动作、结果与发生时已核实的企业范围;不可记录令牌或凭据。 | 现有设计 |
术语表是设计讨论的候选统一语言:企业连接、已验证域名、JIT 和 SSO 策略等不是当前已实现功能。尤其注意已有“组织”“用户组”与客户目录中的同名概念不能自动画等号。
协议与产品参考:OpenID Connect Core · SAML 元数据 · SCIM RFC 7644 · Spring Security SAML · Keycloak 身份代理。
建议先作为 auth 内部边界清晰的模块,与 auth 一起部署;暂不新增独立服务。它仍可以支持多个企业、多种 IdP 和水平扩容。只有当测量或组织需求证明独立部署带来的收益超过跨服务成本,再考虑拆分身份代理。
企业身份连接、登录身份关联、账号和成员资格各自有目的与状态边界。无论是否拆服务都需要。
auth 内独立协议适配、连接配置、登录编排,接口清晰;仍可随 auth 一起部署。
独立进程、资源、发布与运维;可单独扩容,但引入网络、故障和安全契约。
| 方案 | 适合 | 代价与判断 |
|---|---|---|
| A · auth 内联邦模块 建议起步 | 少量协议起步,多个企业动态配置;与账号关联、挑战及会话在同一应用边界内协作。 | 可与 auth 整体水平扩容;联邦流量不能独立配额部署。按照当前约定用外部持久状态支持跨实例回调,不依赖进程内会话。 |
| B · 独立身份代理 自建或使用成熟产品 | 大量客户连接、OIDC/SAML 等多协议、需要独立升级/隔离或统一服务多个产品。 | 新增服务、运维、网络与信任边界;故障可能影响所有上游登录。明确代理身份、回调、短时证明和密钥管理,避免共享账号数据库写入。 |
| C · 托管身份代理 | 希望较少自运维,接受外部身份服务作为依赖。 | 需评估数据驻留、可用性、成本、客户 IdP 兼容、退出迁移;不能把平台企业授权交给代理默认行为。 |
示意图表达职责,不规定已实现的跨应用接口。连接配置的唯一写入者、管理入口、密钥保存位置及向 auth 发布的最小事实仍需设计;遵守现有应用无同步调用和唯一写入约束。认证、建立账号、接受邀请、取得企业权限分别判定。
| 扩展方向 | 模块内需要具备的能力 | 不能忽略 |
|---|---|---|
| 更多企业 | 持久化、按站点隔离的企业连接配置;有权限的开通、验证、启停;可定位指定连接。 | 企业、IdP 租户、邮箱域名不天然一一对应;域名发现仅用于路由。 |
| 更多协议 | 以稳定的认证结果契约隔离 OIDC、SAML 等适配器,避免协议字段渗透进成员治理。 | 标准化结果仍须保留可信发行方、稳定主体、认证时间等必要事实,不能抹平不同协议安全语义。 |
| 更多实例 | 无状态计算节点;挑战、state / nonce / PKCE verifier 及回调上下文放入共享可靠存储;支持跨实例回调。 | 一次性消费、并发首登、身份键唯一、失败恢复及密钥轮换必须验证;不要依赖粘性会话保证正确性。 |
| 更多身份生命周期场景 | 先明确邀请与身份关联;需要时再扩展 JIT、SCIM、停用与会话撤销。 | 现有 auth 设计对新登录身份默认自动开户;企业 SSO 是否沿用、限制或改为邀请优先需要明确修订,不能直接推断。 |
| 环节 | 关注指标 | 主要措施 |
|---|---|---|
| 上游企业 IdP 与网络 | 每连接成功率、令牌端点延迟、超时、上游限流。 | 设置超时、连接池、按 IdP 限流与隔离;上游故障明确失败,不跨企业回退。独立服务不能加速慢 IdP。 |
| 元数据与公钥 | 发现与 JWKS 缓存命中、刷新耗时及失败率。 | 受控缓存、刷新合并和密钥轮换;规定可信配置、缓存有效期和失败策略,不能无限沿用旧密钥。 |
| auth 回调处理 | 回调 QPS、并发、CPU、验签耗时、p95/p99 与错误率。 | 无状态实例水平扩容,隔离上游 I/O;用压测确认 CPU、线程或连接池瓶颈。 |
| 共享状态与数据库 | 挑战/身份关联写入延迟、锁等待、连接池、重复回调冲突。 | 唯一约束、合理索引、短事务和容量规划;拆进程不能消除共享数据库瓶颈。 |
| 端到端 | 从发起到完成登录的成功率与耗时,按企业 / IdP 分解,并排除用户在 IdP 停留时间做服务端诊断。 | 分段追踪,不记录令牌或敏感声明;预设业务峰值与验收目标后做常态、突发和故障压测。 |
一次登录的可见耗时包含浏览器跳转、用户认证等待、上游 IdP 和本平台处理。平台整体扩容只改善受平台资源约束的部分;新增代理还会带来额外网络跳转与依赖。实际增减须测量,不能先假设拆服务更快或更慢。
若拆分,需先决定代理是否只输出短时、一次性、受众绑定且可验证的认证结果,由 auth 唯一负责账号关联与本地会话;account 仍唯一负责企业成员及角色。补齐来源可信、重放防护、时效、密钥轮换、故障恢复、审计以及接口版本与迁移方案,再调整现有无服务间接口的架构规则。两种方案都要处理多 IdP 的混淆防护;参见 OAuth 安全最佳实践 RFC 9700。
以下为工作区内的参考文件名称;在线版本不公开仓库源文件。