CAS协议原理与代码实现(单点登录 与 单点登出的流程)

CAS协议原理

应用场景

  • 豆瓣公司旗下的有多种服务,豆瓣用户需要一次登录就实现豆瓣旗下所有服务的登录。豆瓣电影、豆瓣读书、豆瓣音乐、豆瓣同城等。
    在这里插入图片描述

以上场景即为单点登录。

传统方式及弊端

  • 将 userinfo 写入Cookie,首先不安全,最重要的是 无法跨域 (cookie是和域绑定的)。

CAS协议就是为实现单点登录而诞生的。

CAS协议原理

  • Yale 大学发起的一个开源项目(基于Java)
  • CAS Server 为独立部署的 Web 应用
  • CAS Client 支持多种客户端

概念解释

  • 单点登录(Single sign-on, SSO):在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
  • 统一用户:多个应用共用一套帐号体系,统一用户是 单点登录 的实现前提。一般,储存用户的公有属性在中央认证服务器。
  • 局部会话(Application Session):业务系统服务器(豆瓣读书、电影等服务器)与 浏览器 的会话。
  • 全局会话(CAS Session):CAS认证服务器(用户中心)与 浏览器 的会话。
  • Service:业务系统的路由,提前在 CAS认证服务器 注册过。
  • Ticket Granted Ticket,TGT:大令牌,记录某用户全局会话的状态。
  • CASTGC,TGC:Ticket Granting Cookie,TGT记录在Cookie中的内容,一般是TGT的id。
  • Service Ticket,ST:小令牌,用来向CAS认证服务器(用户中心)兑换用户信息。一般,限制使用次数或有效期。

组成部分

  • CAS Server:主要负责对用户的认证工作。(用户中心)
  • CAS Client :负责处理对客户端受保护资源的访问请求,登录时,重定向到 CAS Server。(各业务系统,豆瓣读书、电影等)

CAS基本流程

在这里插入图片描述

  • A 访问服务:用户浏览器请求访问 业务系统(读书、电影等)。
  • B 定向认证:业务系统 引导浏览器 重定向 到CAS认证服务器(用户中心)。
  • C 用户登录:用户在 用户中心 完成登录,全局会话记录此次登陆。
  • D 发放票据:CAS服务器产生Service Ticket,并 重定向 到业务系统。
  • E 兑换信息:业务系统用Service Ticket 向CAS服务器 兑换用户信息。

CAS协议的具体流程及细节

建立单点登录,首次访问豆瓣

在这里插入图片描述

  • A: 浏览器请求访问 豆瓣读书。
  • B: 豆瓣读书 引导浏览器 重定向 到 豆瓣用户中心。
    • 携带 Service参数
  • C: 在 用户中心 完成登录,建立全局会话。
    • 验证 Service
    • 生成TGT
    • 在浏览器记录CASTGC,即TGT.id,即 建立全局会话
  • D: CAS服务器产生Service Ticket,并 重定向 到业务系统。
    • 用TGT 签发 ST
    • 重定向到 Service代表的 豆瓣读书 路由
    • 并携带 ST
  • E: 豆瓣读书 用Service Ticket 向 用户中心服务器 兑换用户信息。
    • 豆瓣读书服务器获取 ST
    • 豆瓣读书在后台用 ST 向 用户中心服务器 兑换用户信息,官方使用xml传输信息(本文用JSON代替)
    • 兑换成功后,豆瓣读书 用Session或Cookie 记录用户的登录状态,即 建立局部会话。
第二次访问豆瓣读书

在这里插入图片描述

  • A: 请求携带Session,豆瓣读书判断局部会话有效,即完成登录。
首次访问豆瓣电影

在这里插入图片描述

与首次访问豆瓣读书的流程一样

  • B: 豆瓣用户中心服务器 验证TGT,判断 全局会话是否存在。
    • 请求 携带 存有CASTGC的Cookie
    • 用CASTGC验证TGT,通过后,即可完成用户登录
    • 接着签发ST

以上只是单点登录的流程,完整的单点登录还应该支持单点登出(Single Logout, SLO)

单点登出(SLO)

CAS项目及协议支持单点登出,但是并未给出详细的流程图,作者是根据CAS2.x与CAS3.x的指南文档进行归纳总结得出结论。

在这里插入图片描述

  • A: 浏览器请求 豆瓣读书的 /logout
    • 豆瓣读书 删除Session相关内容,即清除局部会话。
  • B: 豆瓣读书 引导浏览器重定向到 用户中心的 /logout
    • 携带Cookie中的CASTGC
  • C: 清除全局会话
    • 删除 Cookie中的CASTGC
    • 注销 TGC对应的TGT
  • D: 认证服务器 通知所有已登录的业务系统清除局部会话
    • 找到TGT签发的ST,即所有已登录的业务系统(豆瓣电影、音乐)
    • 在后台,通知 所有有关的业务系统(Fire & Forget),携带ST
  • E: 业务系统 接到通知后 清除局部会话
    • 用ST 清除 对应的Session,即 清除对应的局部会话

代码实现(基于Flask)

数据库

CAS认证服务器

  • User:用户表
    • username:用户名
    • password:密码
  • Service:业务系统的服务接入表
    • url:Service的业务路由
    • logout_url:Service的退出路由
  • TGT:大令牌表
    • tgt:ticket_granted_ticket, 大令牌
    • user_id:User.id
    • expires_in:过期时间
    • validate:是否有效(-1:无效,1:有效)
  • ST:小令牌表
    • st:service_ticket, 小令牌
    • user_id:User.id
    • tgt_id:TGT.id,由哪个TGT签发
    • service_id:Service.id
    • used:使用次数,一般限制使用次数
    • expires_in:过期时间
    • validate:是否有效(-1:无效,1:有效)

Client服务器

  • Info:信息表,代表该服务器的用户资源
    • username:用户名
    • info:资源
  • ST:小令牌表,业务系统记录ST的状态,用于根据ST删除对应的Session
    • st:service_ticket, 小令牌
    • validate:是否有效(-1:无效,1:有效)

关键点与扩展

  • CAS认证服务器需要验证Service的有效性(提前注册),避免被攻击。
  • TGT只是代表用户登录,不对应Service。而ST对应Service。
  • SLO,业务系统收到CAS认证服务器通知后,根据ST来删除对应的Session,本文只是在 Client数据库 注销了对应的ST。因为,每次登陆时,会验证ST有效性。
  • SLO的业务系统可以根据具体业务需要不支持清除局部会话,比如邮件等业务。
  • Flask的原生session机制是存储在浏览器,而不是通常session存储在服务器,可以利用flask_session重构session存储机制,或 定制flask的session模块代码。

项目代码

如需代码,请联系本人

参考资料

猜你喜欢

转载自blog.csdn.net/weixin_42359693/article/details/85400701