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