1、基本框架图和相关概念
基本框架图:
相关术语概念:
1、结构体系
CAS Server:CAS Server 负责完成对用户的认证工作 , 需要独立部署 , CAS Server 会处理用户名 / 密码等凭证(Credentials)。
CAS Client:负责处理对客户端受保护资源的访问请求,需要对请求方进行身份认证时,重定向到 CAS Server 进行认证。(原则上,客户端应用不再接受任何的用户名密码等 Credentials )。
2、CAS 系统中的票据: TGC、TGT 、 ST 、 PGT 、 PGTIOU 、 PT 。
(1)、TGC(ticket-granting cookie)
授权的票据证明,由 CAS Server 通过 SSL 方式发送给终端用户,存放用户身份认证凭证的Cookie,在浏览器和CAS Server间通讯时使用,并且只能基于安全通道传输(Https),是CAS Server用来明确用户身份的凭证。
(2)、TGT(Ticket Grangting Ticket)
TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,CAS生成Cookie(叫TGC),写入浏览器,同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是Cookie的值。当HTTP再次请求到来时,如果传过来的有CAS生成的Cookie,则CAS以此Cookie值为key查询缓存中有无TGT ,如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。
(3)、ST(Service Ticket)
ST是CAS为用户签发的访问某一service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含Cookie,则CAS会以此Cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。
(4)、PGT(Proxy Granting Ticket)
Proxy Service的代理凭据。用户通过CAS成功登录某一Proxy Service后,CAS生成一个PGT对象,缓存在CAS本地,同时将PGT的值(一个UUID字符串)回传给Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以为Target Service(back-end service)做代理,为其申请PT。
(5)、PGTIOU(Proxy Granting Ticket I Owe You)
PGTIOU是CAS协议中定义的一种附加票据,它增强了传输、获取PGT的安全性。
PGT的传输与获取的过程:Proxy Service调用CAS的serviceValidate接口验证ST成功后,CAS首先会访问pgtUrl指向的Https URL,将生成的 PGT及PGTIOU传输给proxy service,proxy service会以PGTIOU为key,PGT为value,将其存储在Map中;然后CAS会生成验证ST成功的XML消息,返回给Proxy Service,XML消息中含有PGTIOU,proxy service收到XML消息后,会从中解析出PGTIOU的值,然后以其为key,在Map中找出PGT的值,赋值给代表用户信息的Assertion对象的pgtId,同时在Map中将其删除。
(6)、PT(Proxy Ticket)
PT是用户访问Target Service(back-end service)的票据。如果用户访问的是一个Web应用,则Web应用会要求浏览器提供ST,浏览器就会用Cookie去CAS获取一个ST,然后就可以访问这个Web应用了。如果用户访问的不是一个Web应用,而是一个C/S结构的应用,因为C/S结构的应用得不到Cookie,所以用户不能自己去CAS获取ST,而是通过访问proxy service的接口,凭借proxy service的PGT去获取一个PT,然后才能访问到此应用。
2、TGT、ST、PGT、PT之间关系
ST是TGT签发的。用户在CAS上认证成功后,CAS生成TGT,用TGT签发一个ST,ST的ticketGrantingTicket属性值是TGT对象,然后把ST的值redirect到客户应用。
PGT是ST签发的。用户凭借ST去访问Proxy service,Proxy service去CAS验证ST(同时传递PgtUrl参数给CAS),如果ST验证成功,则CAS用ST签发一个PGT,PGT对象里的ticketGrantingTicket是签发ST的TGT对象。
PT是PGT签发的。Proxy service代理back-end service去CAS获取PT的时候,CAS根据传来的pgt参数,获取到PGT对象,然后调用其grantServiceTicket方法,生成一个PT对象。
2、流程剖析
1 、登录
认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。那其他的系统如何访问受保护的资源?这里就是通过认证中心间接授权通过令牌来实现,当SSO验证了用户信息的正确性后,就会创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。
上面是一张SSO登录原理图,下面我们来分析一下具体的流程:
1:用户访问A系统,经过他的第一个过滤器(cas提供,在web.xml中配置)AuthenticationFilter,判断是否登录,如果没有登录则重定向到认证中心。
2:A系统发现用户没有登录,则返回浏览器重定向地址->CAS认证中心。
3:浏览器接收到重定向之后发起重定向,请求CAS认证中心。
4:CAS认证中心接收到登录请求,返回登陆页面。
5:用户在CAS认证中心的login页面输入用户名密码,提交。
6:CAS认证中心接收到用户名密码,则验证是否有效,验证逻辑可以使用cas-server提供现成的,也可以自己实现。
7:浏览器从 CAS认证中心 拿到ticket之后,就根据指示重定向到A系统,请求的url就是上面返回的url。
8:A系统在过滤器中会取到ticket的值,然后通过http方式调用CAS认证中心验证该ticket是否是有效的。
9:CAS认证中心接收到ticket之后,验证,验证通过返回结果告诉A系统该ticket有效。
10:A系统接收到CAS认证中心的返回,知道了用户合法,展示相关资源到用户浏览器上。
11:用户在A系统正常上网,突然想访问B系统,于是发起访问B系统的请求。
12:B系统接收到请求,发现第一次访问,于是给他一个重定向到找CAS认证中心登录。
13:浏览器根据12返回的CAS认证中心地址,发起重定向,因为之前访问过一次了,因此这次会携带上次返回的Cookie:TGC到CAS认证中心。
14:CAS认证中心收到请求,发现TGC对应了一个TGT,于是用TGT签发一个ST,并且返回给浏览器,让他重定向到B系统。
15:浏览器根据14返回的B系统网址发起重定向。
16:B系统获取ticket去CAS认证中心验证是否有效。
17:CAS认证中心接收到ticket之后,验证,验证通过返回结果告诉B系统该ticket有效
18:认证成功之后,session中设置登录状态,可以访问B系统资源了。
用户登录成功之后,会与SSO认证中心及各个子系统建立会话,用户与SSO认证中心建立的会话称为全局会话,用户与各个子系统建立的会话称为局部会话,局部会话建立之后,用户访问子系统受保护资源将不再通过SSO认证中心,全局会话与局部会话有如下约束关系:
a.局部会话存在,全局会话一定存在
b.全局会话存在,局部会话不一定存在
c.全局会话销毁,局部会话必须销毁
2 、注销
既然有登陆那么就自然有注销,单点登录也要单点注销,在一个子系统中注销,所有子系统的会话都将被销毁。原理图如下:
SSO认证中心一直监听全局会话的状态,一旦全局会话销毁,监听器将通知所有注册系统执行注销操作,具体的流程:
1、用户向系统1发起注销请求
2、系统1根据用户与系统1建立的会话id拿到令牌,向SSO认证中心发起注销请求
3、SSO认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址
4、SSO认证中心向所有注册系统发起注销请求
5、各注册系统接收SSO认证中心的注销请求,销毁局部会话
6、SSO认证中心引导用户至登录页面
3、登录状态判断
用户到认证中心登录后,用户和认证中心之间建立起了会话,这个会话称为全局会话。当用户后续访问系统应用时,我们不可能每次应用请求都到认证中心去判定是否登录,这样效率非常低下,这也是单Web应用不需要考虑的。
可以在系统应用和用户浏览器之间建立起局部会话,局部会话保持了客户端与该系统应用的登录状态,局部会话依附于全局会话存在,全局会话消失,局部会话必须消失。
用户访问应用时,首先判断局部会话是否存在,如存在,即认为是登录状态,无需再到认证中心去判断。如不存在,就重定向到认证中心判断全局会话是否存在,如存在,按1提到的方式通知该应用,该应用与客户端就建立起它们之间局部会话,下次请求该应用,就不去认证中心验证了