OAuth Client 标识、认证与用户身份的区别
区分 OAuth client_id、客户端认证、用户登录和 Token 授权,并解释公开客户端为何通常用 PKCE 而不是静态密钥。
#synthesis
#growing
#security
#auth
#http
[!info] related notes
OAuth Client 标识、认证与用户身份的区别
范围
这里区分四个常被混为一谈的问题:哪个应用在请求、应用能否证明自己的身份、哪个用户在授权、Token 最终允许做什么。它们通常出现在同一 OAuth 流程,但由不同机制负责。
核心关系
| 问题 | 典型证据 | 边界 |
|---|---|---|
| Client identification:应用声称自己是谁 | client_id、已登记的 metadata | 标识本身不是秘密,也不一定构成可信证明 |
| Client authentication:调用方能否证明有权使用某客户端身份 | client_secret、private_key_jwt、mTLS 等适用机制 | 公开客户端通常不能保管共享秘密 |
| 用户 authentication:授权的是哪个用户 | 授权服务器的登录 Session / OIDC 身份机制 | 用户登录不等于允许某应用读取任意数据 |
| Delegated authorization:应用获得什么访问权 | consent、grant、带 audience/scope 的 Access Token | Token 验证成功仍需资源级 owner 权限检查 |
公开客户端与机密客户端
- Public client:CLI、移动端、桌面应用、浏览器 SPA 等,分发后不能假设内置的长期凭据保密。常采用授权码 + PKCE,并在授权服务器策略下获取受限 Token。
- Confidential client:具有可信服务器执行环境、能够保管密钥的后端组件,可采用客户端认证。是否真的安全,取决于部署和密钥管理,而不是仅凭“Web App”名称判断。
- Client Authentication 和 PKCE 不是完全互斥的“二选一”;PKCE 主要绑定授权请求与授权码兑换,Client Authentication 是另一种身份凭据校验。
最小例子:Claude Code 连接 MemoFlow
- Claude Code 通过客户端标识/注册机制让 MemoFlow 授权服务器知道允许的回调信息。
- 用户在 MemoFlow 登录:证明 MemoFlow 用户是谁。
- 用户同意
tasks:read:建立 此授权生命周期 的权限。 - 授权码经 PKCE 兑换为 Token;客户端在 HTTP 请求中携带 Bearer Access Token。
- MemoFlow 校验 Token、grant、scope、账户与 Task ownership。不能因为一个
client_id看起来像官方地址,就直接信任调用方。
常见误解
- CIMD metadata 校验不等于客户端认证,也不等于平台信任背书。
- DCR、预注册、CIMD 主要回答如何获得/解析 client registration 信息,而不是取代授权码流程。
client_id没有携带用户数据访问权;真正访问权来自被用户授权、并由资源服务器验证的凭据。- PKCE 解决授权码被截获后的兑换风险,不负责区分“官方二进制”与“仿冒程序”。
- 每个 MCP Host 可以有多条 MCP Client 连接;OAuth 术语中的 client 指授权请求中的应用角色,不能简单等同于大模型本身。
学习检查
- 一个攻击者复制了公开的
client_id,是否就有用户数据访问权? - PKCE 与
client_secret各自证明或保护什么? - 已经 GitHub 登录 MemoFlow,为什么 Codex 还需要用户 consent?
- 为什么校验 Access Token 成功后还必须检查 Goal/Task 的 owner?
- 为什么一个用户可以对 Codex 和 Claude Code 授予不同 scope?