流程:
图文并茂,为你揭开“单点登录“的神秘面纱
这个图片总结的很好,注意两点即可:
- 所有的登录过程都依赖于 CAS 服务,包含用户登录页面、ST 生成、验证;
- 为了保证 ST 的安全性,一般 ST 都是随机生成的,没有规律性。CAS 规定 ST 只能保留一定的时间,之后 CAS 服务会让它失效,而且,CAS 协议规定 ST (CAS给的一次性门票ticket)只能使用一次,无论 ST 验证是否成功,CAS 服务都会清除服务端缓存中的该 ST,从而规避同一个 ST 被使用两次或被窃取的风险。
完整版本:考虑浏览器的场景
上面的过程看起来没问题,实际上很多 APP 等端上这样就够了。但在浏览器下不见得好用。
看这里:
对浏览器来说,SSO 域下返回的数据要怎么存,才能在访问 A 的时候带上?浏览器对跨域有严格限制,cookie、localStorage 等方式都是有域限制的。
这就需要也只能由 A 提供 A 域下存储凭证的能力。一般我们是这么做的:
图中我们通过颜色把浏览器当前所处的域名标记出来。注意图中灰底文字说明部分的变化。
- 在 SSO 域下,SSO 不是通过接口把 ticket 直接返回,而是通过一个带 code 的 URL 重定向到系统 A 的接口上,这个接口通常在 A 向 SSO 注册时约定
- 浏览器被重定向到 A 域下,带着 code 访问了 A 的 callback 接口,callback 接口通过 code 换取 ticket
- 这个 code 不同于 ticket,code 是一次性的,暴露在 URL 中,只为了传一下换 ticket,换完就失效
- callback 接口拿到 ticket 后,在自己的域下 set cookie 成功
- 在后续请求中,只需要把 cookie 中的 ticket 解析出来,去 SSO 验证就好
- 访问 B 系统也是一样
总结
- HTTP 是无状态的,为了维持前后请求,需要前端存储标记
- cookie 是一种完善的标记方式,通过 HTTP 头或 js 操作,有对应的安全策略,是大多数状态管理方案的基石
- session 是一种状态管理方案,前端通过 cookie 存储 id,后端存储数据,但后端要处理分布式问题
- token 是另一种状态管理方案,相比于 session 不需要后端存储,数据全部存在前端,解放后端,释放灵活性
- token 的编码技术,通常基于 base64,或增加加密算法防篡改,jwt 是一种成熟的编码方案
- 在复杂系统中,token 可通过 service token、refresh token 的分权,同时满足安全性和用户体验
- session 和 token 的对比就是「用不用cookie」和「后端存不存」的对比
- 单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket,各业务系统配合存储和认证 ticket
