之前我们谈了如何关于单点登录的一些概述,讲到了当跨域名单点登录时,CAS的设计具有参考价值,那么这篇就该谈谈CAS的具体原理了。
CAS指的是Apereo的CAS开源项目,三个字母分别是是Central Authentication Service的首字母缩写。
官方地址:
网址:https://www.apereo.org/projects/cas
git:https://github.com/apereo/cas
官方文档:https://apereo.github.io/cas/5.3.x/planning/Architecture.html#cas-server
截止目前版本已经更新到了5.3.x
前面我们说到不同域名下如何实现单点登录的问题,现在就可以看看CAS如何解决这个问题
CAS分为server端和client端两种
client端:client端是广义上泛指所有使用CAS单点登录的系统,比如a,b两个系统要设置单点登录,那a,b就都是client,狭义上CAS框架提供了client jar包用于其他项目快速接入CAS单点登录,
server端:server是用作身份认证用的,通俗的讲就是用来校验用户名密码的,当然既然要实现多系统单点登录,那肯定不止是校验用户名密码,实质是单点登录的核心,统一认证中心。
假设原来有a,b,c三个系统,三个系统各自有各自的登录模块,那么使用CAS单点登录系统进行单点登录后,a,b,c三个系统分别去除掉原有登录模块,同时分别加入cas-client模块作为CAS服务的client端,同时会加入一个新系统,cas-server作为CAS的server端。
在说到CAS的认证原理时,避免不了ST,TGT,TGC的概念,但这些概念相对抽象,这里我们通过一个具体的认证过程来进行讲解:
先上一张官方时序图(图较大)(可先看下方讲解)
这张图基本比较清晰地说明了CAS的整个认证实现。
有两个接入了CAS单点登录的系统Protected App(以下简称app1)和Protected App#2(以下简称app2)
一个中央认证系统CAS Server
1.当用户访问app1 时,app1检测到用户未登录,于是向浏览器回应状态302让浏览器跳转到CAS server,同时携带一个了一个经过url encode过的参数server,server的值为app1的url地址(如果使用了官方client jar包那么这些过程会自动处理详细的后续讲解)
2.重新向至CAS Server端后,CAS Server端会进行身份验证流程,也就是弹出登录页面,输入用户名密码,需要的话还可以自行改造添加图片验证码,短信验证码等,总的来说CAS Server端验证身份成功后会做几件事
(1)生成CASTGC,简单的说就是一个在CAS Server域名下的cookie,然后这个cookie包括了TGT,那么什么又是TGT呢,有关TGT详细的后续再讲,在此只要理解两点,一、TGT用于全局身份校验,是单点登录认证的核心依据,作用类似于上一篇谈到同二级域名系统间单点登录的跨域cookie,形式是一个字符串。 二、TGT的生成和session有关
(2)APP1跳转至CAS Server的时候携带了一个参数server值为app1 url的参数,这时CAS server会重定向至这个server值也就是app1
(3)重定向过程中生成一个名为ticket的参数,格式为ST-xxxx(也就是ST)
3.重定向到app1后app1获取到ticket参数后会向CAS server发出get请求来验证ticket的正确性
4.CAS server完成验证后会想app1回传XML格式的,可自定义的用户信息
5.接收到用户信息后,app1会向浏览器设置名为JSESSIONID的cookie并重定向至自身
6.浏览器由于重定向再次访问app1并携带刚刚设置的JSESSIONID,app1验证成功后就正式返回请求页面或相应接口内容了
再次访问app1的时序图中,可以看到很简单,由于每次访问都会携带JSESSIONID,所以很容易进行身份校验
当用户访问app1并登录完成后再访问app2时如何实现单点登录呢
1.当用户访问app2 时,app2检测到用户未登录(没有app2下的相应JSESSIONID cookie),于是向浏览器回应状态302让浏览器跳转到CAS server同时携带service参数,与首次访问app1无异
2.当跳转至CAS server时,区别来了,由于用户已经进行过一次登录,CAS server域名下有cookie CASTGC,在访问server时就会携带TGC,server再检测到有CASTGC后就会优先对其中的数据进行校验(也就是TGT),校验成功后重定向回app2并携带参数ST
之后的步骤便与app1无异了
通过对CAS登录流程的粗略分析,我们可以大致了解到CAS认证的核心是server端域名下的cookie校验,通过service参数进行重定向返回接入单点登录系统的项目,通过ST做服务验证,假设不用CAS框架,我们现在也可以模仿CAS的这一流程做出一个大致的跨域单点登录系统了。
为了讲解连贯,我在上面的步骤描述中忽略了许多细节,比如ST实际上只能使用一次,验证完后就会销毁,同时其本身有效时间也很短,登录系统,其实涉及很多安全问题,CAS框架本身是考虑了安全因素在其中的,我们常见的的安全因素有哪些呢,我将在后续文章中继续分享。
在登录过程描述中,我提到TGC,TGT与session有关,了解session,cookie的朋友也一定一看到图就对JSESSIONID这样的变量名有所察觉,而谈到session就有另一个避不开的问题,集群。我相信大部分开发人员并不喜欢使用传统的服务器session共享,使用redis作为存储信息显然是大部分情况下的更优解,那么如果使用CAS框架能否集群部署,如果不能要如何解决呢,我也将会在后续文章中继续分析。