從http驗(yàn)證流程解析CAS單點(diǎn)登錄

JAVA單點(diǎn)登錄有好多種方式,譬如用cookie的domain做,用中間代理做等等,但都需要自行做許多開發(fā)工作。而其中耶魯大學(xué)的開源項(xiàng)目CAS提供了一個一站式解決方案,只需很少的擴(kuò)展即可輕松實(shí)現(xiàn)企業(yè)級單點(diǎn)登錄?;A(chǔ)知識網(wǎng)上其他挺多的,這里我就不詳述了。本文通過分析http請求過程中http header,cookie等數(shù)據(jù)剖析了cas(非代理模式,默認(rèn)驗(yàn)證邏輯。其他如restletAPI等可擴(kuò)展邏輯本文不會覆蓋)的驗(yàn)證流程,在開發(fā)調(diào)試中提供了另一種方便的方式掌控整個流程的關(guān)鍵點(diǎn)。


Cas術(shù)語

TGT: ?cas服務(wù)端生成的每個用戶唯一的ticket。

TGC: ?cas服務(wù)端根據(jù)TGT生成的每個用戶的cookie,其value是TGT。

ST: ???cas服務(wù)端根據(jù)每個應(yīng)用,每個用戶生成的一個ticket,驗(yàn)證一次就銷毀。

Shiro: JAVA權(quán)限管理框架


Cas請求交互總圖



下面將通過兩個客戶端應(yīng)用A、B分別跟cas server端交互來詳述整個交互流程。本文基于CAS 4.x。 CAS 5.X默認(rèn)邏輯一致,只不過通過spring boot進(jìn)行了重新模塊劃分。



客戶端應(yīng)用A訪問跳轉(zhuǎn)Cas Server驗(yàn)證


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攔截請求發(fā)現(xiàn)session中無cas assertion(其實(shí)就是用戶名和ticket)并且沒有ST則跳轉(zhuǎn)CAS server(本項(xiàng)目由于用了shiro重寫攔截邏輯所以是判斷shiro中有沒有保存驗(yàn)證后的用戶信息), server端發(fā)現(xiàn)無TGC跳轉(zhuǎn)配置的CAS登陸URL




Cas server端登陸后http請求過程


1. post提交用戶信息驗(yàn)證:

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端驗(yàn)證通過后產(chǎn)生ST并在location URL后面賦給ticket。此時往客戶端瀏覽器寫入TGC,并且指示瀏覽器重定向到location位置,其正是客戶端應(yīng)用驗(yàn)證ST的路徑。

此步驟產(chǎn)生2個ticket: TGT,ST;產(chǎn)生一個cookie:TGC,此cookie是通過用戶私密信息與TGT加密生成。


2. Cas client驗(yàn)證ST:

http request:

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


此時客戶端應(yīng)用由于受到shiro的保護(hù),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容器產(chǎn)生的session id,其為location中的jsessionid;rememberMe,為shiro為自動登錄配置的。

此步驟驗(yàn)證ST后(通過url connection去cas server驗(yàn)證ST)如果通過則重定向到新頁面(第一次訪問的頁面或者shiro配置的successful url)產(chǎn)生一個新的容器session id。(為何要重新創(chuàng)建session,因?yàn)槠鋾谛碌膕ession中保存登陸了客戶端應(yīng)用的憑證CAS Assertion,其為客戶端驗(yàn)證ST后返回的)到了這步驟以后屬于客戶端自身的邏輯。CAS作用到此為止。


3. 客戶端應(yīng)用頁面




客戶端應(yīng)用A再次訪問


http request:

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



http response:

200 OK

可以看到這次直接就訪問了,也沒有經(jīng)過驗(yàn)證ticket和與cas服務(wù)端交互。此是因?yàn)閟ession中已經(jīng)保存了cas assertion,所以算作登陸了。



客戶端應(yīng)用B訪問


1. 訪問B應(yīng)用首頁

http request:

Get ?http://localhost:8080/


http response:

302 Found

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

可見產(chǎn)生了新的shiro session,并提示跳轉(zhuǎn)CAS服務(wù)端登陸URL。


2. 訪問CAS服務(wù)器登陸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

可見并沒有要求登陸而是直接就提示跳轉(zhuǎn)到location的URL做驗(yàn)證并產(chǎn)生了一個新的ST。這是因?yàn)镃AS服務(wù)端讀取了A應(yīng)用登陸后在瀏覽器生成的TGC, request cookie中帶入了(下圖可以看到),從而認(rèn)為用戶已經(jīng)登陸,所以直接生成ST,并要求重定向到客戶端應(yīng)用B去驗(yàn)證。



3. 驗(yàn)證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應(yīng)用。


4. 訪問B應(yīng)用首頁

如圖




客戶端應(yīng)用A退出

如下圖:


可見登出時發(fā)生四次請求。

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端已經(jīng)清除了A應(yīng)用的ST和瀏覽器的CASTGC

2. 第二次請求:


http request:

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


http response:

302 Found

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

跳轉(zhuǎn)到了客戶端應(yīng)用,發(fā)現(xiàn)新創(chuàng)建了shiro session(sid)和servlet容器session(JSESSIONID)

并且發(fā)現(xiàn)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

正常訪問首頁,但是因?yàn)闆]登陸所以提示要重定向到CAS服務(wù)端去登陸。(如果有了首頁就改為跳轉(zhuǎn)到首頁)


4. 第四次請求

同原來步驟。



Cas總結(jié)

總的來說,cas(非代理模式,默認(rèn)驗(yàn)證邏輯)是用一個cookie(TGC), N個session(N個子系統(tǒng)session,其中存儲了cas receipt)來保證各應(yīng)用的統(tǒng)一登錄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容