OIDC 用户标识设计:sub、邮箱与跨应用隐私

了解如何用签发者和 sub 识别 OIDC 用户、处理邮箱声明变化,以及如何通过 Sudomimus 扇区和用户授权限制身份信息共享。

应用可以完成用户身份认证,而不获取用户的真实邮箱。设计时需要考虑的是:下次访问时如何识别这个用户,以及应用实际需要保留哪些信息。

使用 OIDC 时,应通过经过验证的签发者和主体标识,也就是 iss 和 sub,关联本地用户。邮箱则是需要单独授权共享的个人资料。Sudomimus 还将主体标识限制在扇区内,因此不同扇区的应用会收到同一账户的不同标识。

用经过验证的签发者和主体标识关联用户

iss 表示 OIDC 签发者,sub 表示该签发者身份模型中的用户。两者共同确定应用接受的外部身份。OIDC 声明稳定性规则将这组值定义为用户标识;邮箱和显示名称不具备同样的保证。

应用可以保留自己的本地用户 ID,再为精确的 (issuer, subject) 组合建立唯一关联。只有 OIDC 库验证登录结果后,应用才能使用这些值。验证应包括预期签发者、受众、签名、有效期,以及流程使用的 nonce。仅解码 JWT 载荷不等于验证令牌。

将主体标识视为不透明值。不要解析它来推断账户 ID、组织、邮箱或权限。如果调用 UserInfo,应先确认响应中的 sub 与已验证 ID Token 中的主体一致,再把返回信息关联到本地用户。

值 应用中的用途
已验证的 iss 和 sub 将外部身份关联到本地用户。
email 仅在来源和验证状态符合应用需求时,用作联系信息。
given_name、family_name 或 picture 在信息可用且允许共享时展示个人资料。
本地用户 ID 关联应用中的项目、偏好设置和业务权限。

将邮箱变化与用户身份分开处理

假设用户登录任务应用后,更换了主邮箱。只要 Sudomimus 扇区主体没有变化,应用就应通过 iss 和 sub 找到同一个本地用户。邮箱改变属于资料更新,不应因此创建第二个任务账户。

邮箱也可能因用户未授权共享而缺失,或者根据应用策略返回生成的占位地址。即使邮箱经过验证,它也不是永久用户标识。email_verified 说明邮箱地址的验证状态,不会让该地址成为主体标识。

不要因为邮箱值相同,就自动合并两个外部身份。邮箱相同不足以证明新登录的身份可以访问已有本地账户。

理解扇区的作用

Sudomimus 使用成对标识符(pairwise identifier)。扇区用于组织需要共享用户外部标识的应用。同一扇区中的应用会看到同一用户的相同主体标识;不同扇区中的应用会收到互不关联的主体标识。应用始终无法获取内部账户 UUID。

例如,一家公司可以把任务看板和项目知识库放在同一个扇区,而无关的社区应用使用另一个扇区:

应用 扇区 同一个人的主体标识
任务看板 公司工作区 subject-A
项目知识库 公司工作区 subject-A
社区论坛 社区 subject-B

表中的主体标识仅用于说明,并非实际令牌值。任务看板和知识库按配置共享外部身份。论坛无法通过比较主体标识,建立这种关联。

同属一个扇区,不会让应用共享业务权限或声明授权。知识库仍需管理自己的文档权限;用户允许任务看板读取邮箱,也不代表允许知识库读取。配置模型见成对身份与组织和扇区。

同时控制主体标识与声明共享

不同主体标识可以限制应用通过标识符关联用户。但如果两个应用还获得了相同的真实邮箱,它们仍然可以比较邮箱地址。共享的姓名或账户头像也可能透露信息。使用成对标识符不等于匿名。

因此,Sudomimus 会分别检查每个应用的身份信息共享条件。返回真实信息需要声明策略允许、用户已授权,以及账户中存在相应数据。OIDC 还要求会话包含对应的作用域。例如,email 作用域不能覆盖用户的决定,也不能覆盖应用仅返回合成值的策略。

根据应用需求选择策略:

  • 不需要某个字段时,使用 OFF。
  • 扇区范围内的占位信息已足够时,使用 SYNTHETIC_ONLY。
  • 用户可以拒绝共享,且应用能处理缺失值时,使用 OPTIONAL。
  • 获得真实信息授权前,应用可以使用占位信息时,使用 SYNTHETIC_FALLBACK。
  • 只有真实信息是完成登录或刷新所必需的条件时,才使用 REQUIRED。

合成邮箱使用 proxy.sudomimus.email 域名,并带有 email_verified: false。它们是占位地址,不是经过验证的账户恢复地址。邮件投递没有保证,通知和账户恢复流程不应依赖这些地址。合成值按扇区隔离,共享真实信息的授权则仍然属于各个应用。

身份声明指南说明了完整策略模型。如果实际响应不符合预期,可以阅读OIDC 登录成功,但没有收到邮箱声明。

处理主动变更身份的情况

在同一扇区的普通登录过程中,Sudomimus 主体标识保持一致。用户可以主动轮换扇区主体;将应用移到其他扇区,也会改变身份关联。这些操作与更换主邮箱不同。

主体轮换会替换主体标识及其合成身份信息。Sudomimus 会终止绑定旧主体的应用会话。此后的登录会提供新的外部身份,应用不应通过匹配邮箱或个人资料,自动恢复旧身份关联。

这些变化无法抹去应用已经收到的信息。应用独立创建的本地会话也需要自行管理。只做离线 JWT 验证时,已签发令牌在到期前仍可能被接受;如果操作需要确认 Sudomimus 会话的当前状态,应使用 Session 会话检查接口。

同样,撤销可选邮箱的共享授权,会阻止后续 UserInfo 响应继续披露真实邮箱,但不会删除应用数据库中已经保存的副本。应用需要明确哪些信息必须保留,以及用户停止共享后如何处理这些信息。

用几个具体情况检查接入结果

  1. 不改变主体标识,连续登录两次。确认两次都找到同一个本地用户。
  2. 更换主邮箱,但保留主体标识。确认本地用户及其项目权限保持不变。
  3. 拒绝共享可选邮箱。确认登录仍可完成,应用能处理字段缺失。
  4. 使用合成邮箱策略。确认应用不会把占位地址当成经过验证的账户恢复邮箱。
  5. 轮换扇区主体。确认重新登录时,应用不会自动把新主体关联到旧的本地账户。

关于身份、会话与应用权限之间的关系,可以阅读Sudomimus 是什么:应用登录、会话与身份信息共享。配置协议接入时,请继续阅读 OIDC 接入指南。