第三方 OAuth 接入授权流程
令牌交换
RFC 8693 —— 第一方管理端用会话令牌换取其他受众的短期令牌。
第三方应用用不到这个流程
令牌交换只对 first_party 客户端开放,用于 MuoCeon 自己的管理端把「已登录的用户会话」带进
oauth / account 资源端点。第三方应用的取令牌方式只有授权码流程。
它能解决什么
第一方管理端在浏览器里持有 auth 受众的会话令牌,但要调用的接口属于 oauth(已授权应用管理)或 account(账号资料)受众。直接拿 auth 令牌去调会被受众校验拦下——受众不是建议,是硬边界。令牌交换就是在这条边界上开的一扇窄门:换一枚短期、窄受众的令牌出来。
请求
curl -X POST 'https://id.example.com/v1/oauth/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u "$FIRST_PARTY_CLIENT_ID:$FIRST_PARTY_CLIENT_SECRET" \
-d 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
-d 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
-d "subject_token=$AUTH_ACCESS_TOKEN" \
-d 'audience=oauth' \
-d 'scope=oauth:grants:read'| 参数 | 必填 | 说明 |
|---|---|---|
grant_type | ✅ | urn:ietf:params:oauth:grant-type:token-exchange |
subject_token | ✅ | 一枚有效的 auth 受众访问令牌 |
subject_token_type | ✅ | 只接受 urn:ietf:params:oauth:token-type:access_token |
audience | ✅ | 只能是 oauth 或 account |
scope | 可选 | 只能是目标受众的自管理 scope |
被明确拒绝的用法:
actor_token/ 委托交换——不支持,传了直接报参数错误。requested_token_type非 access token(如要id_token)——不支持。subject_token_type为refresh_token、SAML 断言等——不支持。audience=auth——不允许把令牌换回会话受众。
响应
{
"token_type": "Bearer",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"expires_in": 300,
"access_token": "eyJ...",
"scope": "oauth:grants:read"
}交换出来的令牌有什么不同
| 特性 | 交换令牌 |
|---|---|
| 寿命 | 固定 5 分钟 |
| 存储 | 不落库,无服务端记录 |
| 撤销 | 不能单独撤销,只能等它过期 |
aud | 只含目标受众(oauth 或 account),不含 auth |
| 刷新 | 不签发刷新令牌 |
| 适用范围 | 一次页面加载所需的若干次请求 |
因为不落库,它天然无法被撤销、也无法内省。因此 5 分钟的寿命就是唯一的安全边界:换出来就立刻用,用完即弃,不要缓存到本地存储里跨页面复用。
选受众的规则
- 只读已授权应用列表、撤销授权:
audience=oauth+oauth:grants:read/oauth:grants:revoke。 - 读或改账号扩展资料:
audience=account+account:profile:read/account:profile:write。 - 需要同时用两个受众:换两次,不要指望一枚令牌覆盖两个受众。
相关 scope 的完整清单见 scope 与受众。