cas server:cas
client server: C1
client server: C2
當(dāng)用戶在C1和C2都登錄之后,獲取到改用戶在兩個(gè)系統(tǒng)內(nèi)各自需要的權(quán)限之后,在C1做登出操作,按照網(wǎng)上大部分的配置方法(web.xml中增加SingleSignOutFilter和SingleSignOutHttpSessionListener),可以在效果上看起來是登出了,但是并沒有完全登出。
即:
C1和C2的JSESSIONID對(duì)應(yīng)在服務(wù)器的session被銷毀,瀏覽器兩個(gè)JSESSIONID失效(看起來登出了)
cas的cookie(TGT)失效
C1服務(wù)器上,對(duì)應(yīng)的用戶權(quán)限清除(C1是完全退出了)
C2服務(wù)器上,對(duì)應(yīng)的用戶權(quán)限沒有清除(沒完全退出)
1,2,3都很正常,問題出在第四步。
第四步僅僅是被SingleSignOutFilter攔截,根據(jù)service-ticket銷毀掉改用戶對(duì)應(yīng)的session,而并沒有調(diào)用shiro的subject.logout, 顯然,subject.logout是做了銷毀權(quán)限緩存等操作的
這樣就會(huì)導(dǎo)致最終C2上的用戶權(quán)限沒有被清除,若在此時(shí)用戶權(quán)限被修改,就會(huì)導(dǎo)致即使登出,C2上的權(quán)限也沒有刷新
權(quán)限緩存是可以設(shè)置過期時(shí)間的,那么簡(jiǎn)單點(diǎn),只要給權(quán)限緩存加上過期時(shí)間即可,這樣如果權(quán)限被修改,即使用戶不登出,在過期之后,權(quán)限也會(huì)被刷新
http://howiefh.github.io/2015/05/19/shiro-cas-single-sign-on/ 有一個(gè)很詳細(xì)的說明,但是沒仔細(xì)看,簡(jiǎn)單的說就是使用ServletContainerSessionManager,即shiro自己的session管理,似乎可以解決問題,但是未驗(yàn)證
思路很簡(jiǎn)單,重寫SingleSignOutFilter, 在登出的時(shí)候,調(diào)用subject.logout 即可。
奈何太年輕,這種方案有很多坑
問題:
Subject是由session中存放的一個(gè)key生成的,但是時(shí)序圖中第四步是有cas發(fā)起的請(qǐng)求,而不是用戶瀏覽器,即這個(gè)session中沒有Subject信息,shiro無法獲取到具體信息。
解決:
SingleSignOutFilter中有存儲(chǔ)一份 service-ticket與session的映射關(guān)系,那么只要在第四步中 利用 service-ticket取到session,再從session中取到SimplePrincipalCollection信息放入subject即可
問題:
subject不提供設(shè)置principal接口,service-ticket session映射關(guān)系未提供get接口
解決:
反射搞定,但是總覺得不靠譜呢。。
問題:
SingleSignOutFilter是在ShiroFilter chain之前,也就是說,如果重寫SingleSignOutFilter,在里邊連一個(gè)不包含Principal的Subject都獲取不到,但是如果把這個(gè)SimplePrincipalCollection放到 shrioFilter之后,登錄的時(shí)候又會(huì)有問題
這是一個(gè)雞生蛋和蛋生雞的問題啊。。。
解決:
問題總是能解決的,放在前邊后邊都不行,那么放一起吧。對(duì),把SingleSignOutFilter放到ShiroFilter之中, 原以為ShiroFilter會(huì)對(duì)符合過濾規(guī)則的做一個(gè)filter chain,結(jié)果并不是。
shiro會(huì)針對(duì)配置的filter規(guī)則,取第一個(gè)匹配的作為最終的filter,而后邊符合規(guī)則的就會(huì)被忽略掉
所以這里,要把SingleSignOutFilter和Shiro自己提供的CasFilter合并起來,放在一起作為一個(gè)filter
經(jīng)過這么一折騰,于是就有了下面的代碼了
|
|
代碼邏輯很簡(jiǎn)單,主要是要找到這么個(gè)解決方案,得一點(diǎn)點(diǎn)的調(diào)試和摸索,也是蠻有意思。
另外web.xml中的SingleSignOutFilter需要去掉,因?yàn)槲覀円呀?jīng)移到Shiro里邊了,但是Listener需要保留,并且需要自己重寫(里邊有調(diào)用SingleSignOutFilter的方法,需要改掉), 代碼如下
|
|
準(zhǔn)備找個(gè)時(shí)間寫個(gè)cas的faq,畢竟在開發(fā)過程中,遇到的很多常見問題,很是煩躁。
聯(lián)系客服