SSO 英文全称 Single Sign On, 单点登录. SSO 是在多个应用系统中, 用户只需要登录一次就可以访问所有相互信任的应用系统. CAS 是一种基于 http 协议的 B/S 应用系统单点登录实现方案, 认识 CAS 之前首先要熟悉 http 协议, Session 与 Cookie 等 web 开发基本知识.
1.http 协议
HTTP 是一个客户端和服务器端请求和应答的标准, 我们全后端开发对接的 REST 接口就是基于 http 协议. http 协议包含 http 请求消息 (HttpRequest) 和 http 应答消息 (HttpResponse) 两部分. 参考内容: https://www.cnblogs.com/rayray/p/3729533.html
理解 http 协议是无状态协议的含义
熟记常见的 http 协议状态码, 其中 302 等与 cas 相关
熟记常见的 http 请求头, 其中 Cookie 等与 cas 相关
熟记常见的 http 应答头, 其中 Set-Cookie,Location 等与 cas 相关
2.Session 与 Cookie 会话机制
http 协议本身是无状态的, 但有时候我们需要 http 请求保持状态, 我们引入 Session 与 Cookie.
Session 用在服务端, 用于存储当前所有客户端需要保持的状态值, 并为每一个客户端生成一个唯一编码, 然后通过 http 响应头 Set-Cookie 将这个编码发送给客户端.
Cookie 用在客户端, 用于记录后端发来过的唯一编码, 该编码与服务端上的对应的状态值对应, 在下一次请求的时候通过 http 请求头 Cookie 带上这个编码, 服务端就能根据这个编码获取该客户端之前记录的所有状态值.
3. 普通登录
登录成功后, 在 Session 中写入登录用户的信息, 退出时清空 Session 中的用户信息. 可以通过 filter 实现.
4.CAS 单点登录 | 两次前端跳转, 一次后端验证
4.1 首次访问(访问第一个应用系统 App1)
CAS 首次登录会经过两次前端跳转, 一次后端验证. 在应用系统端需要集成 CasClient 的 jar 包, 把其中的 filter 配置到站点 Web.xml 中, 用于拦截请求, 判断登录, 发起跳转或发起验证等. 在 SSO 服务器上部署 CasServer 的 war 包, 需要配置用户数据源, 根据需求修改登录页面.
第一次跳转: 客户端访问应用系统, 应用系统判断 Session 发现未登录, 返回 302 跳转到 sso 登录页面, 并传递 service 参数给 sso, 该 service 参数有两个作用:
service 一般传递应用系统 url 地址, 用于 sso 认证通过后回跳到应用系统;
service 参数同时会被 cas 服务端的作为 cas 客户端的唯一标记记录下来, 用于后期匹配相应的认证凭据;
第二次跳转: 浏览器显示登录页面, 用户输入账号密码登录成功后, sso 会返回 302 跳转回到原来请求的应用系统页面, 并携带 ticket 参数, 作为认证票据, 同时通过 Set-Cookie 向浏览器记录 TGT,(TGT 的作用将在下一个应用系统需要登录的时候体现出作用, 是避免重复登录的关键)
一次后台验证: 应用系统接收到带有 ticket 的请求后, 从后台直接向 sso 服务器发起一个 http 请求, 将 service 和 ticket 作为参数, 用于验证 ticket 的有效性; 如果 ticket 有效, sso 服务器将返回该 ticket 对应的登录用户名.
4.2 再次访问(访问第二个应用系统 app2)
当用户已经登录过一个应用系统以后, 在同一个浏览器上访问第二个应用系统, 根据单点登录的要求此时不应该再登录, 而是直接进入第二个系统. 但是实际上还是需要经过两次前端跳转, 一次后端验证, 只不过此时的两次跳转是连续的, 中间不会再出现登陆页面, 用户感受不到. 判断的依据就是前面第 4 步通过 Set-Cookie 保存到客户端的 TGT(Ticket Granted Cookie ).
相比首次访问, 少了之前的第 3 步(不需要再出现登录页面), 因为此时在第二步跳转时, 携带了之前保存的 TGT,cas 服务端通过 TGT 可以得知用户信息, 因此直接生成 ticket 返回给应用系统. 所以此时是两次连续的 302 跳转, 用户看到的效果就是直接进入第二个应用系统了.
5. 案例讲解
5.1 循环跳转异常案例
异常现象说明: 某项目前后端分开部署出现这样一个现象, 前端映射域名为 http://xxx.gov.cn/zpsgl, 后端映射域名为 http://xxx.gov.cn/zpsgl/rest, 单独访问后端登录没有任何问题, 但是访问前端登陆后界面出现反复跳转不停刷新的问题.
异常排查: 循环跳转原理, SSO 登录后返回应用系统, 应用系统后台认证获取用户信息存入 Session, 由于某种原因造成 Session 信息丢失, 导致应用系统认为还未登录, 于是又跳转 SSO, 此时 SSO 已经登录不会再出登陆页面, 直接生成 ticket 返回应用系统, 应用系统 Session 再次丢失, 进入反复跳转认证的死循环, 前端界面表现为不停的刷新.
因此关键问题在于分析 Session 信息丢失的原因, 一般来讲有两种可能: 1 是系统本身逻辑问题把之前写入 Session 的登录信息清空了, 2 是两个站点的 cookie 作用域相同而相互覆盖, 从而导致后台 Session 被重置.
分析发现该项目属于第二种情况, 前后端 cookie 都在 http://xxx.gov.cn / 域下面, 解决办法修改 cookie 作用域或者修改 cookie 中 Jsessionid 的命名, 防止相互覆盖.
来源: https://www.cnblogs.com/ArtofDesign/p/10566329.html