KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

SSO 应用课 · 课程导读 — keel 龙骨

SSO 工程课:协议、令牌与会话 的参考信息:SSO 应用课 · 课程导读

这门课不站在「怎么把 SSO 接进来」的起点上,而是站在接进来之后它不按预期工作的起点上。

认证这一层有个特点:它对的时候什么也不说。跳转成功、令牌拿到、用户进来——
一切顺利时你看不到任何东西。只有它坏了,你才会看到一堆参数名:
code、state、nonce、session_state、iss、kid……
它们每一个都对应一条一次性的约束,而故障几乎总是「某条约束在步骤之间被破坏」。

七章的顺序是刻意排的:

先站到高处(01 选型)
  → 把一次登录逐步走通(02 授权码流 + PKCE)
  → 把它带回来的三样东西拆开(03 令牌与校验)
  → 回答「为什么第二次不用再登录」(04 会话与登出)
  → 把视角从一个应用抬到多个系统(05 联邦与多租户)
  → 用前面所有结论去制造故障(06 故障注入与排障)
  → 把教学替身逐条换成真实依赖(07 生产边界)

你现在的起点

先花一分钟对一下。下面五条你都能说清,这门课的前两章可以直接跳读:

其中任何一条答不上来,都属于本课的读者面。

主案例:一个 IdP、两个应用、两个用户

全课用一个案例反复演进,不换例子:

角色 标识 说明
IdP realm sso-lab,issuer http://localhost:8081/realms/sso-lab 唯一签发身份结论的一侧
应用 A sp-spa,公开客户端 + PKCE,回跳 http://localhost:8090/callback 拿不到凭证的客户端,只能靠 PKCE
应用 B sp-portal,机密客户端 + client_secret,回跳 http://localhost:8091/callback 有服务端的一侧,能保守秘密
用户 alice 两个应用都要认成同一个人
用户 bob 用来验证「不是所有登录都等价」

两个客户端刻意选了两种类型:04 章的单点登录判据、06 章的一整类故障
(client_secret 放在哪里、能不能放进前端)都靠这个对比才说得清楚。

course/project/ 里这套配置是同一份,代码化之后可以改、可以断、可以注入。

章节地图

章节 关键问题 产物落点
01 全景与选型 为什么会有「登录」这件事变得复杂?三条协议各在哪一层?我这个场景选哪个? 一张分层对照表 + 一个选型判断顺序
02 授权码流与 PKCE 第一步 GET 为什么给的是登录页?回跳的四个参数各是什么?PKCE 防住了谁? 一次完整登录的逐步报文(含失败路径)
03 令牌与校验 三个 token 各管什么?JWT 三段与 kid?每一项校验漏了会出什么事? 一张「claim → 防什么 → 漏了会怎样」对照表
04 会话与登出 单点登录靠什么成立?「已登录」记在哪一侧?登出为什么要清两处? 单点登录/单点登出的判据 + 前后 cookie 对照
05 联邦与多租户 一个应用接多家 IdP 怎么区分?sub 能当账号吗?企业接入要交换什么? 一份企业接入清单 + 账号关联与离职回收的路径
06 故障注入与排障 断了怎么定位?五类典型故障各自长什么样? 一张「症状 → 去哪看 → 根因」表
07 生产边界 单实例够用吗?会话存哪?密钥怎么轮换?代理后面 issuer 为什么变了? 一张「教学替身 → 真实替换点」表

你会反复用到的三种「看」

  1. 看报文:不猜实现,直接看请求 URL、响应状态码、回跳参数、令牌里的 claim。
    协议层的一切都能用「谁发给谁、带了什么、状态码多少」说清。
  2. 看载体:某个状态被记在了哪一侧——浏览器 cookie、IdP 会话、应用自己的 session、
    令牌本身。单点登录与单点登出的全部难点都在这里。
  3. 看一次性能不能用:code 用一次、nonce 绑一次、at_hash 绑一次、
    refresh token 可以重复用(默认不做 reuse detection)——这几条不对称的规则正是故障来源。

三个必须先纠偏的认知

  1. code 不是 token,它换不出任何东西。 它只是一张经过浏览器、必须再带上
    code_verifier 才能兑换的凭据。把它当成「已经登录」是排障时第一个要排掉的假设。
  2. 令牌验过签名 ≠ 这次登录合法。 签名只说明「这段内容确实是 IdP 签的」,
    还要逐个比对 iss / aud / exp / nonce / at_hash——少一项就是一个可被利用的口子。
  3. 单点登录不是「IdP 记得你」,是「浏览器还带着那个 cookie」。 换个浏览器、
    换个设备、清了 cookie,同一个用户就要重新登录一次。这条决定了它在哪些场景里做不到你要的效果。

配套项目与本课的关系

course/project/ 是一个只用标准库的最小 OIDC 实现(一个最小 OP + 一个最小 RP + 一个会管 cookie 的浏览器)。
正文每一处「报文里到底交换了什么」都能在它里面找到对应的代码行,每条失败路径都有对应的测试断言。

学习顺序建议:先读正文建立判断,再跑 examples/01 看完整流程,
最后自己改一处代码去制造 06 章里的故障
。

读完之后

前置要求

进入 keel 阅读