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。(各业务系统,豆瓣读书、电影等)

基本流程

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,即 清除对应的局部会话

数据库

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模块代码。

posted @ 2020-04-07 14:20  洛神灬殇  阅读(1610)  评论(0编辑  收藏  举报