KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

00 · IdP 与 SP(依赖方) — keel 龙骨

类型:主题概念 · 应用课对应:01 章 · 全景与选型

类型:主题概念 · 应用课对应:01 章 · 全景与选型

这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。它不解释协议报文,也不讲选型。

一、它为什么会出现

一个团队里同时跑着四个内部系统:工单、报表、监控、代码托管。它们是不同的人在几年里分别搭起来的,每个系统都有自己的账号表。

于是每天都发生这几件事:

新人入职 → 开四个账号,漏掉一个,他第一天就有系统进不去
有人调岗 → 四个系统里改四遍权限,改到最后自己也记不清改到哪了
有人离职 → 只要漏关一个,他的密码还能登进去

它面对的需求是一句话:让"这个人是谁"这件事只被验证一次,所有系统都接受同一个结论。

不是"把四个系统合并成一个",也不是"给四个系统同步密码"——那两条路都要求每个系统继续自己保管密码。它要的是把验证这件事从每个系统里搬走。

二、它是什么

一句话:IdP 是那个"替所有应用验证身份"的系统;SP 是那些"不自己验密码、只接受 IdP 结论"的应用。

两个名字:

角色 全称 在这个故事里是谁
IdP Identity Provider,身份提供方 唯一一个存密码、问密码、判对错的地方
SP Service Provider,依赖方(OIDC 里也叫 RP) 工单、报表、监控、代码托管——四个都属于它

它不是下面这三样东西,分清它们能省掉一大半困惑:

三、它长什么样

"谁是 IdP、谁是 SP"落成配置,是两处登记:SP 侧登记"我信谁",IdP 侧登记"我认得谁"。

SP 侧的登记:

issuer       = http://localhost:8081/realms/sso-lab
client_id    = sp-spa
redirect_uri = http://localhost:8090/callback

IdP 侧的登记:

client_id    = sp-spa
redirect_uri = http://localhost:8090/callback
public client, no client_secret

两边对 redirect_uri 必须逐字符一致——它是安全边界,02 页 专门讲。

真跑起来时,IdP 的身份会以 iss 的名义出现在回跳地址里(环境:Keycloak 26.8.1,dev 模式,realm = sso-lab):

http://localhost:8090/callback
  ?state=AsoTwZFFJyDK-urhFMy_jw
  &session_state=VnXksyjhgJexcsLOoOE5fc8c
  &iss=http%3A%2F%2Flocalhost%3A8081%2Frealms%2Fsso-lab
  &code=44f80113-b402-a38e-bbc0-56310447ebf8.VnXksyjhgJexcsLOoOE5fc8c.74717848-0bf1-4f44-81f2-e31422eb12c8

iss 里那个 http://localhost:8081/realms/sso-lab,就是 IdP 在发现文档里自报的 issuer:

issuer               = http://localhost:8081/realms/sso-lab
authorization_endpoint = http://localhost:8081/realms/sso-lab/protocol/openid-connect/auth
token_endpoint         = http://localhost:8081/realms/sso-lab/protocol/openid-connect/token
end_session_endpoint   = http://localhost:8081/realms/sso-lab/protocol/openid-connect/logout

它必须和你实际访问它的地址逐字符一致。 如果你的应用从 http://127.0.0.1:8081 去访问,而文档里写的是 localhost,那么回跳里的 iss 与令牌里的 iss 都会是 localhost 那个值——和你在 SP 侧登记的 issuer 对不上,校验当场失败。这不是大小写写错了,而是 IdP 的"名字"就长在它的地址上。

四、它怎么工作

一次登录只有四步,其中一步是关键:

① 应用发现"这个访问者在我这儿没有会话" → 把浏览器交给 IdP
   ↓
② IdP 在自己的地址上问凭据        ← 只有这一步会看到密码,且发生在 IdP 的页面上
   ↓
③ IdP 把一段"这个人是谁"的结论交回应用
   ↓
④ 应用据此建自己的会话;此后每个请求只查自己的会话,不再回头问 IdP

第 ② 步是整件事的核心:密码从来没有经过应用。所以第 ④ 步之后,应用手里拿的是"有人替我确认过身份"这件事,而不是密码。

也正因为第 ② 步由 IdP 独占,第 ③ 步才能被第二个应用复用——两个应用问的是同一个 IdP。

五、它会带出哪些概念

六、回到应用课

应用课里的那句话 现在你知道它为什么成立
"认证:你是谁;授权:你能做什么 + 数据隔离" IdP 只回答前一个问题;SP 拿到"是谁"之后能不能做某件事,仍然由 SP 自己判断
"把'验身份'收敛到一个系统去做,其余系统只接受它的结论,就是单点登录" 这句话里的"一个系统"就是 IdP、"其余系统"就是 SP——角色先立住,后面每个判断才有主语
"对面用什么协议往往不是你能选的" 两套协议换的是同一段结论的不同载体;"对面是谁"之所以一票决定,是因为要动的是 SP 侧接哪一段

这一页改变了你的哪个判断:你不再只问"登不上怎么修",而是先问**"这一步是 IdP 在说、还是 SP 在说"**——同一句"登录失败",出在 IdP 侧和出在 SP 侧,要去核对的东西完全不同。

→ 这一页的展开在应用课 01 章 · 全景与选型。

自测题

  1. 既然"SP 与 SP 之间从不说话",第二个应用凭什么认定"这个人就是刚才那个人"?
  2. IdP 的发现文档写着 issuer = http://localhost:8081/realms/sso-lab,而你从 http://127.0.0.1:8081 访问它——会在哪一步、以什么形式出问题?

进入 keel 阅读