Skip to content
marstone edited this page Nov 24, 2023 · 32 revisions

0. 概述

  • 账号主体(Principal) 是指企业内机读的、共识的 人员标识

​1. 人员结构解释

type User {
 ​# OpenID: 随机生成、人读不友好,为默认账号主体openid: str() 
 ​# 用户名:用于登录、人读友好。可用于账号主体,但不推荐 userName: str()
 ​# 身份列表 identities: [{
   ​# 身份类型(即,身份类别岗):如 员工、教师、本科生post: str() 
   ​# 身份编码:该身份的证件编码,如,工号、学号,可作为 `兼容模式` 的账号主体 code: str() 
 ​}]
}

2. 配置逻辑

  • 账号主体 需满足条件:唯一、稳定( => 无语义 => 人读不友好)
  • 账号主体 可配置为 openid身份编码
  • 账号主体配置 可逐应用、逐服务(关联到应用)配置

3. "身份编码"作为账号主体的影响

3.1. 对登录逻辑的影响

  • 登录应用允许登录的用户身份集合Sa,用户该次登录合法的身份集合Su,则:
    • Sa ∩ Su = Ø:报错
    • (Sa ∩ Su) 的身份编码集合的元素数 = 1:使用该身份编码
    • (Sa ∩ Su) 的身份编码集合的元素数 > 1:请用户自主选择所有合法身份(可记住选择)
  • 如应用不显式配置允许登录的用户身份集合,则默认所有身份均可登录
  • 用户该次登录合法的身份集合Su的计算方式:
    • 如用户使用用户名等人员属性登录,则Su为用户所有有效的身份类型岗的身份集合
    • 如用户使用特定身份编码登录,则Su为用户符合该身份编码的身份集合

3.2. 对 id_token 的影响

{
  "aud": str(),
  "iss": str(),
  "jti": str(),
  #  openid,除非 sso 工作在桥接模式下(不检测本地账号) 
  "sub": str(),  
  "exp": int(),
  "iat": int(),
  "name": str(),
  "email": str(),
  "phone_number": str(),
  "nonce": str(),
  "at_hash": str(),

  # Principal相关的扩展字段
  # OAuth的token内省时,token参数的持有应用的身份主体
  "principal": enum("OPENID", "USER_CODE", "USERNAME"),
  # 内省系统(access_token提供者)的身份主体,仅内省时返回,因内省调用者而异
  "servicePrincipal": enum("OPENID", "USER_CODE", "USERNAME"),  
  # 账号主体,除 OAuth内省 之外,均按 principal 设置。内省时使用 servicePrincipal
  # 如果该主体信息不存在,则返回空字符串
  "account": str(),    

  # 其他扩展字段
  "tenant": str(),     # 该用户所属的租户代码
  "userCode": str(),   # 身份编码,使用默认身份逻辑[1],仅无身份时为空
  "userType": str(),   # 身份类型
  "sid": str(),        # 会话ID,表示一次登录。多次漫游视为同一会话 
  "mfa": str(),        # Token发放时,该会话已验证、未过期的多因子列表,空格分隔 
  "mfaSession": str(), # Token内省时,该会话已验证、未过期的多因子列表,空格分隔 
}
  • [1] 默认身份逻辑:默认身份可因不同场景采用不同规则,比较常见的包括:
    • 身份优先级:由身份治理时按规则确定,一个自然人有多身份时,优先级最高的身份视为默认身份
    • 用户预设置:对于多身份用户,可自由配置其要使用的默认身份
    • 登录时选择:对于多身份用户,每次登录、漫游时,可选择当次会话的默认身份(也包括 记住上次选择 等辅助手段)

3.3. 对EnterpriseAPI的影响

  • 当 EnterpriseAPI 被调用时,根据调用者的 access_token.principal 确定所属应用
  • 对于调用者的应用所配置的 账号主体 决定 /users 和 /occupies 返回内容的用户id
  • 对于账号主体为身份编码的应用,users 按身份编码拆分,occupies 按身份编码复制。

举例:
对于人员 张三,工号 007、学号 110,则,

users = [ 
   { account:007, name:张三 }, 
   { account:110, name:张三 } 
]
occupies = [ 
  { account:007, postCode:教师, userCode:007 }, 
  { account:007, postCode:学生, userCode:110 }, 
  { account:110, postCode:教师, userCode:007 }, 
  { account:110, postCode:学生, userCode:110 }, 
]

4.场景调用链分析

场景

编号 适用场景 登录方式 人员数据 是否合重 平台方案 流程大厅方案
场景A 非治理场景 身份编号 身份编号 不合重 人员ID 身份编码
场景B 遗留治理场景,学工号登录 身份编号 身份编号 合重 人员ID 身份编码/人员ID(转历史)
场景C 完全治理场景+别名 身份编号 人员ID - 人员ID 人员ID
场景D 不推荐 人员ID 身份编号 不合重 人员ID 身份编码,需选身份
场景E 遗留治理场景,用户名登录 人员ID 身份编号 合重 人员ID 人员ID
场景F 完全治理场景 人员ID 人员ID - 人员ID 人员ID

调用链

登录方式 应用Principal 服务Principal 登录获取token 用户参数 网关$ACCOUNT OAuth的Token内省
身份编号
场景ABC
身份编号 人员ID 身份编号 身份编号:服务兼容 身份转ID 身份转ID
身份编号 身份编号 透传 透传
人员ID 人员ID 身份编号暗示 人员ID 透传 透传
身份编号 ⛔不支持 ID转身份 ID转身份
人员ID
场景EDF
身份编号 人员ID 身份编号:选身份 身份编号:服务兼容 身份转ID 身份转ID
身份编号 身份编号 透传 透传
人员ID 人员ID 人员ID 人员ID 透传 透传
身份编号 ⛔不支持 默认身份 默认身份
  • 注:登录方式,是进入给到sso的用户标识,这包括:
    • 身份编号:包括直接输入身份编号+密码登录、上游认证因子(企业sso或企业微信等)返回身份编号
    • 人员ID:包括使用用户名、邮箱、手机号等标识人员信息的内容登录,或者上游认证因子返回此类人员信息

5.用户标识的显示

问题概述

  • 问题:用户界面在很多场景下需要显示用户的标识,但当身份主体为人员ID(尤其是openid)时,直接显示并不友好。
  • 方案:身份平台在所有人员身份信息的接口中提供 accountFriendly 字段用于显示。accountFriendly 字段为空时,应用仍需显示按 account 显示,以兼容原逻辑

具体设计

  • accountFriendly的来源配置(租户配置)
    1. 所有身份编号:默认。多个号码之间使用逗号分隔,没有身份则使用用户名
    2. 默认身份编号:使用默认身份的身份编码,没有身份则使用用户名
    3. 用户名优先:同【1】,只是用户名和所有身份优先级调换
  • 提供 accountFriendly 的接口,包括但不限于,
    • iam/users、iam/me 等用户查询的接口,支持返回结果中提供此字段,并支持按此字段搜索
    • EnterpriseAPI 中人员接口
Clone this wiki locally