续期、撤销与退出¶
访问令牌、刷新令牌、SAI 登录状态和应用自己的 Cookie 有不同的有效期。应用 Cookie 尚未到期,不代表 SAI 令牌仍可续期。
在线续期¶
普通网页应用使用获批的在线刷新流程,不请求 offline_access。当前默认 SSO 闲置期限为 30 分钟、最长期限为 12 小时;客户端登记可以进一步收紧。以实际令牌响应和登记政策为准,不硬编码永久登录,也不把刷新理解为延长绝对上限。
根据 token 响应的 expires_in 安排到期前续期;不要等到应用 Cookie 到期才刷新。同一登录会话的并发请求共用一次刷新,收到响应后原子保存新的 access token 和 refresh token。
POST /realms/sai/protocol/openid-connect/token HTTP/1.1
Host: id.open-sai.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&client_id=example-web&refresh_token=CURRENT_REFRESH_TOKEN&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=FRESH_CLIENT_ASSERTION
请求仍使用登记的客户端认证;Basic 客户端通过 HTTP Basic 头认证。刷新令牌轮换,旧令牌不得继续使用。对响应不明的超时不要并发或循环重放同一刷新令牌;按客户端库与应用的失败恢复策略处理,必要时重新发起 OIDC 登录。
invalid_grant 表示本次凭据不能继续使用,结束对应的本地登录,再进入普通 OIDC 登录流程。有效 SSO 可以直接继续;确实需要用户认证时才显示登录表单。网络故障、502/503/504 或客户端认证配置错误都不能直接解释成用户退出,详见错误处理。
区分用户意图¶
| 操作 | 应用需要做什么 |
|---|---|
| 退出当前应用 | 失效本地应用会话;是否同时结束 SAI SSO 应在产品中明确 |
| 撤销令牌 | 使用 revocation endpoint 撤销对应授权凭据,再清理相关本地凭据 |
| 结束 SAI SSO | 使用 RP-Initiated Logout,处理已登记的退出返回地址 |
| 撤销应用授权 | 用户在 SAI 账号的应用授权页操作,应用应停止续期并重新取得授权 |
| 撤销指定会话或全部会话 | 用户在 SAI 账号中选择相应操作;应用按退出通知及令牌有效期处理本地会话 |
注销、撤销授权和删除业务数据是不同操作。网页退出不会结束已建立的 SSH 连接或计算作业;也不能假定普通浏览器退出会撤销另行批准的离线授权。
撤销令牌¶
POST /realms/sai/protocol/openid-connect/revoke HTTP/1.1
Host: id.open-sai.com
Content-Type: application/x-www-form-urlencoded
client_id=example-web&token=TOKEN_TO_REVOKE&token_type_hint=refresh_token&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=FRESH_CLIENT_ASSERTION
使用登记的客户端认证;JWT assertion 的 audience 按接入配置使用 token endpoint。RFC 7009 的成功响应通常为空,未知或已失效令牌也可返回成功。它不能证明所有应用、所有用户或所有资源缓存都已失效。
如果业务服务只在本地验签,不向 SAI 检查令牌状态,已经签发的访问令牌可能在到期前仍可使用。应用应明确这一延迟,并按约定处理退出。
RP-Initiated Logout¶
从 Discovery 读取 end_session_endpoint。建议使用浏览器 POST 提交,避免将 ID token hint 写进地址栏:
POST /realms/sai/protocol/openid-connect/logout HTTP/1.1
Host: id.open-sai.com
Content-Type: application/x-www-form-urlencoded
client_id=example-web&id_token_hint=ID_TOKEN_FOR_THIS_SESSION&post_logout_redirect_uri=https%3A%2F%2Fapp.example.org%2Fsigned-out&state=RANDOM_LOGOUT_STATE
应用先保存退出事务的 state,回到准确登记的地址后核验它。缺少 hint 时引擎可能要求用户确认,不能用猜测的令牌或其他账号令牌绕过。退出结果页不应立即自动发起登录,否则用户会感觉退出无效。
服务端退出通知(Back-Channel Logout)¶
登记你自己的 HTTPS backchannel_logout_uri。SAI 以 POST 表单发送 logout_token,不是浏览器导航:
POST /oidc/backchannel-logout HTTP/1.1
Host: app.example.org
Content-Type: application/x-www-form-urlencoded
logout_token=SIGNED_LOGOUT_TOKEN
使用 OIDC 库验证签名、iss、aud、iat、jti 和标准 logout event;要求 sid 或 sub,并拒绝包含 nonce 的 logout token。按 (iss, client, sid) 或经验证的相应 subject 范围失效本地会话,记录已处理的 jti 并设置合理的保留期限,防止重复处理。不能仅解析 JWT 内容后就执行退出。
这个端点无需浏览器 Cookie,也不能依赖浏览器 CSRF 令牌,但每次请求必须验证签名退出令牌。重复的合法退出应安全幂等,成功后返回 HTTP 200。实现会话失效后再返回成功,不以收到 HTTP 请求代替完成处理。
如果应用暂时无法接收退出通知,仍须在令牌到期或约定的检查时间重新验证登录状态,不能无限期保留本地登录。