从http验证流程解析CAS单点登录

JAVA单点登录有好多种方式,譬如用cookie的domain做,用中间代理做等等,但都需要自行做许多开发工作。而其中耶鲁大学的开源项目CAS提供了一个一站式解决方案,只需很少的扩展即可轻松实现企业级单点登录。基础知识网上其他挺多的,这里我就不详述了。本文通过分析http请求过程中http header,cookie等数据剖析了cas(非代理模式,默认验证逻辑。其他如restletAPI等可扩展逻辑本文不会覆盖)的验证流程,在开发调试中提供了另一种方便的方式掌控整个流程的关键点


Cas术语

TGT:  cas服务端生成的每个用户唯一的ticket。

TGC:  cas服务端根据TGT生成的每个用户的cookie,其value是TGT。

ST:    cas服务端根据每个应用,每个用户生成的一个ticket,验证一次就销毁。

Shiro: JAVA权限管理框架


Cas请求交互总图



下面将通过两个客户端应用A、B分别跟cas server端交互来详述整个交互流程。本文基于CAS 4.x。 CAS 5.X默认逻辑一致,只不过通过spring boot进行了重新模块划分。



客户端应用A访问跳转Cas Server验证


http request:

GET  http://uc.54315.com/myWhListManager


http response:

302 Found

Location: https://passport.jzt.com/login?service=http://uc.54315.com/casuc

Cas client拦截请求发现session中无cas assertion(其实就是用户名和ticket)并且没有ST则跳转CAS server(本项目由于用了shiro重写拦截逻辑所以是判断shiro中有没有保存验证后的用户信息), server端发现无TGC跳转配置的CAS登陆URL




Cas server端登陆后http请求过程


1. post提交用户信息验证:

http request:

Post https://passport.jzt.com/login?service=http://uc.54315.com/casuc


http response:

302 Found

Location:http://uc.54315.com/casuc?ticket=ST-1-0kdGxVoshSZz2Bp6kMaA-cas01.example.org

Response返回302指示重定向。同时可见response返回两个cookie: CASPRIVACY=和CASTGC=TGT-1-MRebCegmlpucavmxcPqCUMVc496IiJgl06BGyJ736D7c4UPkCw-cas01.example.org

也就是说:cas server端验证通过后产生ST并在location URL后面赋给ticket。此时往客户端浏览器写入TGC,并且指示浏览器重定向到location位置,其正是客户端应用验证ST的路径。

此步骤产生2个ticket: TGT,ST;产生一个cookie:TGC,此cookie是通过用户私密信息与TGT加密生成。


2. Cas client验证ST:

http request:

Get  http://uc.54315.com/casuc?ticket=ST-1-0kdGxVoshSZz2Bp6kMaA-cas01.example.org


此时客户端应用由于受到shiro的保护,request cookie中就不是JSESSIONID而是shiro的SessionId:sid,uuid模式,其与第一步中的sid一致。


http response:

302Found

Location:http://uc.54315.com/myWhListManager;jsessionid=qqwn1wmrsymy47n8udvf7v2s

Response返回302指示重定向到另一个页面(第一次访问的页面或者shiro配置的successful url),同时可见生成了新的session和sessionID。同时可见response返回2个cookie:  JSESSIONID,为servlet容器产生的session id,其为location中的jsessionid;rememberMe,为shiro为自动登录配置的。

此步骤验证ST后(通过url connection去cas server验证ST)如果通过则重定向到新页面(第一次访问的页面或者shiro配置的successful url)产生一个新的容器session id。(为何要重新创建session,因为其会在新的session中保存登陆了客户端应用的凭证CAS Assertion,其为客户端验证ST后返回的)到了这步骤以后属于客户端自身的逻辑。CAS作用到此为止。


3. 客户端应用页面




客户端应用A再次访问


http request:

Get  http://uc.54315.com/getUcUserRegister



http response:

200 OK

可以看到这次直接就访问了,也没有经过验证ticket和与cas服务端交互。此是因为session中已经保存了cas assertion,所以算作登陆了。



客户端应用B访问


1. 访问B应用首页

http request:

Get  http://localhost:8080/


http response:

302 Found

Location: https://passport.jzt.com/login?service=http://localhost:8080/casuc

可见产生了新的shiro session,并提示跳转CAS服务端登陆URL。


2. 访问CAS服务器登陆URL

http request:

Get  https://passport.jzt.com/login?service=http://localhost:8080/casuc


http response:

302 Found

Location: http://localhost:8080/casuc?ticket=ST-2-wtWpPg2Sv4d00fXecLSI-cas01.example.org

可见并没有要求登陆而是直接就提示跳转到location的URL做验证并产生了一个新的ST。这是因为CAS服务端读取了A应用登陆后在浏览器生成的TGC, request cookie中带入了(下图可以看到),从而认为用户已经登陆,所以直接生成ST,并要求重定向到客户端应用B去验证。



3. 验证ST

http request:

Get  http://localhost:8080/casuc?ticket=ST-2-wtWpPg2Sv4d00fXecLSI-cas01.example.org


http response:

302 Found

Location: http://localhost:8080/;jsessionid=1jh99lja6wzxw1jweg8ss40yt8

步骤同A应用。


4. 访问B应用首页

如图




客户端应用A退出

如下图:


可见登出时发生四次请求。

1. 第一次请求:

http request:

GET  https://passport.jzt.com/logout?service=http://uc.54315.com:80/logout


http response:

302 Found

Location: http://uc.54315.com:80/logout

直接访问CAS server端的登出url。Cookie中有CASTGC和server端的JSESSIONID。

返回中CASTGC清空,CASPRIVACY清空。 此时说明server端已经清除了A应用的ST和浏览器的CASTGC

2. 第二次请求:


http request:

Get  http://uc.54315.com/logout


http response:

302 Found

Location: http://uc.54315.com/

跳转到了客户端应用,发现新创建了shiro session(sid)和servlet容器session(JSESSIONID)

并且发现rememberMe和SID的cookie都被换成deleteMe啦。 此为shiro的loginout拦截器干的好事。



3. 第三次请求:

http request:

Get http://uc.54315.com/


http response:

302 Found

Location: https://passport.jzt.com/login?service=http://uc.54315.com/casuc

正常访问首页,但是因为没登陆所以提示要重定向到CAS服务端去登陆。(如果有了首页就改为跳转到首页)


4. 第四次请求

同原来步骤。



Cas总结

总的来说,cas(非代理模式,默认验证逻辑)是用一个cookie(TGC), N个session(N个子系统session,其中存储了cas receipt)来保证各应用的统一登录。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容