cas的诞生是为了解决单点登录问题,本质还是为了解决session的共享问题.
假设我的spring security不整合cas,那么怎么解决单点登录,也许你会想到许多类似cas的框架,但是若是没有这些框架,你要怎么实现:
1.将session复制到每一个服务器?那么服务一多,响应时间不就很长了;
2.使用一个中间件,redis或者传统的关系型数据库?传统型数据库,io操作一多,性能不就低了吗,redis可以实现,但是存在内存限制的问题.
3.也许还有zookeeper监察机制的解决方法;
有怎么多种的解决方法,我们为什么还需要像cas这样的框架呢?我说了一句废话
Σ( ° △ °|||)︴,谁都想站巨人的肩膀上.要是我们自己实现,需要考虑安全等许多问题,这样为了一个简单功能,这样做就得不偿失了,而框架就解决了我们的顾虑.以cas为例.
在第一访问的时候,cas会生成三个东西(不知怎么描述,感觉ticket不是很确切):
1.TGT(Ticket Grangting Ticket)
存储在cas server中,类似于session(感觉就是session);
2.TGC(Ticket Granted Cookie)
存储在web browser中,类似于jsessionid.好了tgt和tgc的关系,你可以类比为session和jsessionid(tomcat生成用于存储session的id的cookie名称)的关系,每次登陆cas server时,报文都会携带该cookie进行验证,判断用户是否为已登录用户,免用户名密码验证;既然tgc这么重要,那怎么保证安全性,这就不用你担心了,对此,cas实现了ssl(Secure Sockets Layer),避免了tgc被窃取的可能,也许有狠人.
3.ST(service ticket)
居然,上面这两种东西这么重要,那么我的cas client的ticket什么,就是ST,鉴于ST的重要性,只能使用一次,且存在时间极短(5min吧),意思就是cas client拿到ST,将其传输到server进行验证,通过了,ST就立马销毁,不存在二次消费的可能.ST是不进行存储的,直接通过url进行传参.
说了这么多,按照我的理解概括,client判断无用户登录信息,将其重定向至server判断是否登录,然后发送一个票据(st)给client进行验证,验证通过了会开启会话(session),然后在浏览器存储一个jsessionid,下次重复登录,自己client就可以直接放行,不需要通过server.(好了,这里预埋一个坑,翻了一堆的源码,没有找到确切点.大致是,cas client会判断当前访问是有状态还是无状态,然后一套逻辑,判断当前访问的合法性,问题就在于,不同的client开启会话都会生成各自jsessionid,导致其它的client的jessionid被覆盖.结果就是交差访问不同的服务,会导致每次访问都需要重定向至server进行验证)
访问流程
说了再多,也不如图片来的实在,接下来逐图分析spring security整合cas的3种登录流程(和cas流程差不多,区别就在secutity的权限控制的细粒度更高,还有就是开启session的时机不一样):
-
系统第一登录,访问A(9107)服务
1.1 Web browser请求访问cas client,cas client先判断是否用户登录,没有用户登录信息,在验证是否有ticket,都没有,将信息重定向至cas server.下图:
1.2 重定向至cas server,提交用户名密码验证,成功后的报文
Σ( ° △ °|||)︴,图没有截取,jsessionid会不一致,将就吧
1.3 重定向至cas client,验证票据
1.3 重定向至A 服务,访问成功
- 系统登录成功,访问B(9106)服务
2.1 A服务登录成功,访问B服务的资源,这时client重定向至server会携带CASTGC的cookie信息,进行匹配验证,省去用户登录的操作.
2.2重定向至cas server
2.3重定向至cas client
- 连续访问相同服务的情况
不管是单纯的cas还是spring security整合cas的情况,当第一次访问该服务成功以后(secutity整合cas,不管成功还是失败会先开启会话;单纯的cas是ST验证通过之后开启会话),接下去,在不访问其他服务的情况下,继续访问该服务,不需要借助cas server验证,自己就可以根据jsession和自身的session进行验证,用户是否登录了该服务.
4. 交叉访问同一服务器下,不同端口号
在这种情况下,由于jssessionid的名称相同,导致cas客户端的局部会话(session)失效,导致频繁的访问cas服务器,产生过多的无效session对象。
解决方法:修改tomcat的session的cookie的名称即可。(设置流程请自行百度)
其实还是有很多坑,留着以后有空再分析,还有其他的任务等着我,不能直接吊死在这可树上.
cas架构图:来自cas官方文档
当分析完cas的验证流程,感觉只有垂直结构比较符合,cas的验证流程和思想,其中无意间浏览到官方文档的,其中的架构图,也验证了我的思想.