CAS认证和注销过程
CAS是中央认证服务的简称,是SSO的一种可靠的解决方案。
简介
SSO:Single Sign On的,即单点登录,一次登录可以访问所有信任的系统。
CAS:Central Authentication Service - 中央认证服务,是SSO的一种解决方案。
CAS角色
CAS server:中央认证服务,用于校验用户、给用户授权等。
CAS clients:即所有需要通过CAS server认证的系统。如Jbone项目的jbone-sys-admin
CAS名词解读
TGT:Ticket Grangting Ticket,即CAS给用户签发的票据。持有有效的TGT的用户就可以证明CAS成功登录过。
TGC:Ticket-granting cookie,即保存在客户端(浏览器)的TGT。用户单点登录验证时会携带TGC交给CAS server,Cas server会从TGC中解析出TGT,并验证用户的登录有效性。
ST:Service Ticket,即CAS为用户的某一个服务签发的票据。当用户首次访问信任的service时,如果没有ST则需要向CAS server获取ST,创建系统Session之前需要向CAS Server校验ST的有效性。验证通过后再保存当前service的Session。如果验证失败则不会保存服务端session。注意ST只能使用一次。
CAS认证和注销过程
下图为jbone项目中cas的认证和单点注销流程图,技术选型是cas+pac4j+shiro;
CAS认证流程
用户第一次访问A系统
- 用户访问http://a.majunwei.com,浏览器GET请求至http://a.majunwei.com,这时受保护的A系统还没有认证过,所以没有对应的用户session,需要302重定向到cas server,即https://cas.majunwei.com/cas/login?service=http://a.majunwei.com/cas/client_name=CasClient;
- CAS Server解析TGC,因为没有登录过,所以TGC是空的,验证失败,跳转到CAS登录页面;
- 用户在登录页面输入用户名、密码后,提交登录请求。POST到CAS server,即https://cas.majunwei.com/cas/login?service=http://a.majunwei.com/cas/client_name=CasClient;
- CAS Server验证用户后首先保存TGC,然后302重定向到http://a.majunwei.com/cas/client_name=CasClient&ticket=ST-XXX;注意这里携带了服务的ST票据。
- 浏览器GET请求到http://a.majunwei.com/cas/client_name=CasClient&ticket=ST-XXX;
- A系统解析到ticket参数,说明是授权后的回调请求,这时A系统的过滤器会发起serviceValidate的验证,验证ST的有效性。
- 验证通过后生成并保存A系统的Session,以及SessionId和ticket的对应关系(用户后面的单点登出)。
- 保存A系统的Session Cookie:JESSIONID=XXXXX;
- 302重定向到http://a.majunwei.com;
- 浏览器GET请求到http://a.majunwei.com(注意这里浏览器已经有了A系统的JESSIONID)
- A系统解析到JESSIONID,验证SESSION有效(注意在Jbone项目里用了redis保存共享session,所以存取都是从redis里取的)
- 200 返回http://a.majunwei.com。
- 用户看到http://a.majunwei.com。
用户第二次访问A系统
- 用户第二次访问A系统:http://a.majunwei.com/x.action,浏览器GET请求至http://a.majunwei.com/x.action;
- A系统解析到JESSIONID,验证SESSION有效(注意在Jbone项目里用了redis保存共享session,所以存取都是从redis里取的)
- 200 返回:http://a.majunwei.com/x.action
- 用户看到http://a.majunwei.com/x.action
用户第一次访问B系统
- 用户请求B系统,http://b.majunwei.com,浏览器GET请求至http://b.majunwei.com
- B系统没有检查到JESSIONID,所以302重定向至https://cas.majunwei.com/cas/login?service=http://b.majunwei.com/cas/client_name=CasClient
- 浏览器GET请求https://cas.majunwei.com/cas/login?service=http://b.majunwei.com/cas/client_name=CasClient,CAS Server解析到CASGC,并验证TGT的有效性。验证通过后说明已经登录过,然后302重定向到http://b.majunwei.com/cas/client_name=CasClient&ticket=ST-XXX;
- 浏览器GET请求http://b.majunwei.com/cas/client_name=CasClient&ticket=ST-XXX;(注意这里携带了服务的ST票据)。
- B系统解析到有ticket参数,说明是授权后的回调请求,在后台发起serviceValidate的ST校验。
- 校验通过后生成并保存B系统的Session,然后记录SessionId和ticket的关系(用于后面的单点登出)。
- 保存B系统的Session Cookie:JESSIONID=XXX
- 302重定向至http://b.majunwei.com
- 浏览器GET请求至http://b.majunwei.com;(注意这里浏览器已经有了B系统的JESSIONID)
- B系统解析到JESSIONID,验证SESSION有效(注意在Jbone项目里用了redis保存共享session,所以存取都是从redis里取的)
- 200 返回http://b.majunwei.com。
- 用户看到http://b.majunwei.com。
单点登出流程
单点登出,即在一个系统登出,会注销掉当前用户所有信任服务的授权。如在jbone-sys-admin里点击了退出,会同时退出jbone-tag-admin,再次访问jbone-tag-admin系统,也会跳转至登录页面进行重新授权。
- 用户在A系统中注销,GET请求http://a.majunwei.com.logout
- A系统销毁当前Session
- 302重定向至https://cas.majunwei.com/cas/logout?service=http://a.majunwei.com/cas/client_name=CasClient
- 浏览器GET请求至CAS Server,https://cas.majunwei.com/cas/logout?service=http://a.majunwei.com/cas/client_name=CasClient
- CAS Server解析客户端Cookie CASTGC,并销毁TGT票据。
- CAS Server通知当前TGT下认证过的所有服务(包括A系统),POST http://b.majunwei.com/cas?client_name=CasClient。注意这里请求中会携带当前系统(即B系统)的ST等认证信息。
- B系统解析到是登出通知(请求中有logoutRequest参数),然后获取Ticket并通过Ticket和SessionId的关系,销毁对应的Session。
- 返回给用户登出成功提示页面
- 用户看到登出成功提示页面。
- 用户再次访问任意系统,都会跳转至登录页面。
注意:单点登出后会遍历所有授权过的系统,进行登出通知。