關于shiro session失效報錯問題

最近做了一個項目,要用到shiro,做完之后發現有個異常經常發生org.apache.shiro.session.UnknownSessionException: There is no session with id?,經過多天的研究,終于得以解決


登錄的時候異常信息:

[java]?view plain?copy
  1. org.apache.shiro.session.UnknownSessionException:?There?is?no?session?with?id?[4e8fe40a-6347-4c53-b273-829889656f6e]??
  2. ????at?org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)[251:org.apache.shiro.core:1.2.3]??
  3. ????at?org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)[251:org.apache.shiro.core:1.2.3]??
  4. ????at?org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)[251:org.apache.shiro.core:1.2.3]??
  5. ????at?org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)[251:org.apache.shiro.core:1.2.3]??
  6. ????at?org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:108)[251:org.apache.shiro.core:1.2.3]??
  7. ????at?org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupRequiredSession(AbstractNativeSessionManager.java:112)[251:org.apache.shiro.core:1.2.3]??
  8. ????at?org.apache.shiro.session.mgt.AbstractNativeSessionManager.getAttribute(AbstractNativeSessionManager.java:209)[251:org.apache.shiro.core:1.2.3]??
  9. ????at?org.apache.shiro.session.mgt.DelegatingSession.getAttribute(DelegatingSession.java:141)[251:org.apache.shiro.core:1.2.3]??
  10. ????at?org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)[251:org.apache.shiro.core:1.2.3]??
  11. ????at?org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)[251:org.apache.shiro.core:1.2.3]??
  12. ????at?org.apache.shiro.subject.support.DelegatingSubject.getRunAsPrincipalsStack(DelegatingSubject.java:469)[251:org.apache.shiro.core:1.2.3]??
  13. ????at?org.apache.shiro.subject.support.DelegatingSubject.getPrincipals(DelegatingSubject.java:153)[251:org.apache.shiro.core:1.2.3]??
  14. ????at?org.apache.shiro.subject.support.DelegatingSubject.getPrincipal(DelegatingSubject.java:149)[251:org.apache.shiro.core:1.2.3]??

為何找不到呢,原因是這樣的。

當用戶登錄的時候,web容器tomcat或者jetty會在線程池里面啟用線程調度,線程里面找到對應的servlet,shiro登錄的時候代碼如下

[java]?view plain?copy
  1. <span?style="white-space:pre">????</span>Subject?currentUser?=?SecurityUtils.getSubject();??
  2. ??????????
  3. ????????String?sessionId?=?"";??
  4. ??
  5. ????????if?(!currentUser.isAuthenticated())?{??
  6. ??????????????UsernamePasswordToken?token?=?new?UsernamePasswordToken(username,?DigestUtils.md5Hex(passwd));??
  7. ??????????????token.setRememberMe(true);??
  8. ??????????????currentUser.login(token);??
  9. ?????????}??


方法SecurityUtils.getSubject()源碼是這樣

[java]?view plain?copy
  1. public?static?Subject?getSubject()?{??
  2. ????????Subject?subject?=?ThreadContext.getSubject();??
  3. ????????if?(subject?==?null)?{??
  4. ????????????subject?=?(new?Subject.Builder()).buildSubject();??
  5. ????????????ThreadContext.bind(subject);??
  6. ????????}??
  7. ????????return?subject;??
  8. }??


我們清楚的看到subject是從ThreadContext獲取,創建過就直接從里面獲取,沒有創建的話就重新創建一個subject,然后綁定到ThreadContext,調用subject獲取session的時候,他會去創建一個session,并且把session緩存起來,操作方法是在AbstractSessionDAO類里面,跟蹤得知這里放的是subject的代理對象。如果session超時時間設置過短的話,在用戶登錄的時候,隨著web容器分配的線程,很大的機會會分配之前的線程,而之前的線程綁定過了subject,subject沒有失效,subejct對象里面的session也沒有什么問題,但是session緩存里面的session失效了,用戶登錄的時候執行到currentuser.login(token)這個方法,他拿著之前的session,那后要去緩存里面讀取,但是已經失效了,所以會報上面那個異常。


問題就是出現在這里,subject綁定到thread上下文里面,subject對象的session是個代理對象,正真的session是放在緩存里面,web容器隨機分配的線程有可能綁定過subject,一旦session失效,就會報錯。


解決的辦法是在shiro去讀取session之前判斷有沒有失效,如果失效移除ThreadContext里面的subject,并且刪除緩存里面的session,代碼如下

[java]?view plain?copy
  1. @Override??
  2. ????public?String?login(String?username,?String?passwd)?{??
  3. ??????????
  4. ????????Subject?currentUser?=?SecurityUtils.getSubject();??
  5. ????????//提前1秒去判斷???防止這個if沒進??等執行下面的時候它卻失效了??<span?style="font-family:?Arial,?Helvetica,?sans-serif;">lengthenTimeOut是失效時間</span>??
  6. ??
  7. ????????if((System.currentTimeMillis()-currentUser.getSession().getStartTimestamp().getTime())>=lengthenTimeOut-1000){??
  8. ????????????ThreadContext.remove(ThreadContext.SUBJECT_KEY);//移除線程里面的subject??
  9. ????????????shiroSessionManager.getSessionDAO().delete(currentUser.getSession());//移除失效的session??
  10. ????????????currentUser?=?SecurityUtils.getSubject();//重新獲取subject??
  11. ????????}??
  12. ??????????
  13. ????????String?sessionId?=?"";??
[java]?view plain?copy
  1. ????try?{??
  2. ????????if?(!currentUser.isAuthenticated())?{??
  3. ????????????UsernamePasswordToken?token?=?new?UsernamePasswordToken(username,?DigestUtils.md5Hex(passwd));??
  4. ????????????token.setRememberMe(true);??
  5. ????????????currentUser.login(token);??
  6. ????????}??
  7. ?????????
  8. ????????sessionId?=?currentUser.getSession().getId().toString();??
  9. ??????????
  10. ??
  11. ????}?catch?(ExcessiveAttemptsException?ex)?{??
  12. ????????log.info(username?+?"帳號被鎖定1小時!",?ex);??
  13. ????}?catch?(UnknownAccountException?uae)?{??
  14. ????????log.info(username?+?"賬戶不存在!",?uae);??
  15. ????}?catch?(IncorrectCredentialsException?ice)?{??
  16. ????????log.info(username?+?"密碼不正確!",?ice);??
  17. ????}?catch?(LockedAccountException?lae)?{??
  18. ????????log.info(username?+?"賬戶被禁了!",?lae);??
  19. ????}?catch?(AuthenticationException?ae)?{??
  20. ????????log.info(username?+?"用戶名或密碼錯誤!",?ae);??
  21. ????}?catch?(UnknownSessionException?ue)?{??
  22. ????????log.info("登錄session失效"?+?sessionId,?ue);??
  23. ??????????
  24. ????}??
  25. ??
  26. ????log.info("登錄成功返回的sessionId+++++++++++++"?+?sessionId);??
  27. ????return?sessionId;??
  28. }??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387428.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387428.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387428.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

4 網絡、掛載、關機

網絡命令: 給在線用戶發信 write 用戶名 編輯時&#xff0c;Ctrl退格鍵刪除錯誤輸入 CtrlD 保存輸入信息 wall 給所有在線用戶發信 ping命令 -c指定發送次數 ping -c 3 192.168.231.1 ifconfig 查看網卡信息 ifconfig eth1 192.168.231.100 臨時設置IP地址 mail 用戶名 …

#191 sea(動態規劃)

假設已經求出了i個點j個橋的連通圖數量f[i][j]&#xff0c;容易由此推出最終答案&#xff0c;套路地枚舉1號點所在連通塊大小即可。 假設已經求出了i個點的邊雙連通圖數量h[i]&#xff0c;考慮由此推出f[i][j]。可以枚舉其中一座橋將圖劃分成兩個部分&#xff0c;固定1號點在其…

linux下獲取占用CPU資源最多的10個進程,可以使用如下命令組合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下

linux下獲取占用CPU資源最多的10個進程&#xff0c;可以使用如下命令組合&#xff1a; ps aux|head -1;ps aux|grep -v PID|sort -rn -k 3|head linux下獲取占用內存資源最多的10個進程&#xff0c;可以使用如下命令組合&#xff1a; ps aux|head -1;ps aux|grep -v PID|s…

自定義注解與validation結合使用案例

案例1&#xff1a; [java] view plaincopy import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import…

5 Vim編輯器的使用

vi filename 命令模式 a i o 插入模式 后前 行 Esc鍵 回到命令模式 Shift&#xff1a; 編輯模式 set nu加行號 執行完命令后直接回到命令模式 :set nu 設置行號 :set nonu 取消行號 移動命令&#xff1a; gg 到第一行 G 到最后一行 nG 到第n行 :n到第n行 $ 移至行…

機器學習實戰(筆記)------------KNN算法

1.KNN算法 KNN算法即K-臨近算法&#xff0c;采用測量不同特征值之間的距離的方法進行分類。 以二維情況舉例&#xff1a; 假設一條樣本含有兩個特征。將這兩種特征進行數值化&#xff0c;我們就可以假設這兩種特種分別為二維坐標系中的橫軸和縱軸&#xff0c;將一個樣本以點的形…

hive的安裝配置

hive只需安裝在一個節點上。 1、將安裝包解壓&#xff0c;cd入conf文件夾下&#xff0c;執行命令cp hive-default.xml hive-site.xml 2、更改hive-site.xml的配置項 </property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql:/…

Java注解Annotation 完成驗證

Java注解Annotation用起來很方便&#xff0c;也越來越流行&#xff0c;由于其簡單、簡練且易于使用等特點&#xff0c;很多開發工具都提供了注解功能&#xff0c;不好的地方就是代碼入侵比較嚴重&#xff0c;所以使用的時候要有一定的選擇性。 這篇文章將利用注解&#xff0c;來…

隱藏馬爾科夫模型HMM

概率圖模型 HMM 先從一個具體的例子入手,看看我們要解決的實際問題.例子引自wiki.https://en.wikipedia.org/wiki/Hidden_Markov_model Consider two friends, Alice and Bob, who live far apart from each other and who talk together daily over the telephone about what …

常用HQL

進入hive客戶端后&#xff1a; 1、建表&#xff1a; create table page_view(viewTime int, userid bigint,page_url string, referrer_url string,ip string comment IP Address of the User)comment This is the page view tablepartitioned by(dt string, country string)r…

阿里云天池 金融風控訓練營Task1 廣東工業站

Task1 賽題理解 一、學習知識點概要 本次學習先是介紹了賽題的背景和概況&#xff0c;題目以金融風控中的個人信貸為背景&#xff0c;給所給的47列特征中&#xff0c;根據貸款申請人的數據信息預測其是否有違約的可能&#xff0c;以此判斷是否通過貸款。隨后介紹了比賽中的評…

如何將.crt的ssl證書文件轉換成.pem格式

如何將.crt的ssl證書文件轉換成.pem格式摘自&#xff1a;https://www.landui.com/help/show-8127 2018-07-04 14:55:41 2158次 準備:有一臺安裝了php的linux操作系統執行下面的openssl命令即可&#xff1a;openssl x509 -in www.xx.com.crt -out www.xx.com.pem轉載于:https://…

SpringMVC學習記錄--Validator驗證分析

一.基于Validator接口的驗證. 首先創建User實例,并加入幾個屬性 ?12345678910111213141516171819202122232425262728293031323334<code class"hljs cs">public class User {private String username;private String password;private String nickname;public …

NTP時間服務器實現Linux時間同步

在linux下&#xff0c;可以通過自帶的NTP(Network Time Protocol)協議通過網絡使自己的系統保持精確的時間。 什么是NTP&#xff1f; NTP是用來使系統和一個時間源保持時間同步的協議。 在自己管理的網絡中建立至少一臺時間服務器來同步本地時間&#xff0c;這樣可以使得在不同…

阿里云天池 Python訓練營Task1:從變量到異常處理

本學習筆記為阿里云天池龍珠計劃Python訓練營的學習內容&#xff0c;學習鏈接為&#xff1a;https://tianchi.aliyun.com/specials/promotion/aicamppython?spm5176.22758685.J_6770933040.1.6f103da1tESyzu 目錄 一、學習知識點概要 二、學習內容 I.變量、運算符與數據類…

python回收機制

目錄 Python的垃圾回收機制引子:一、什么是垃圾回收機制&#xff1f;二、為什么要用垃圾回收機制&#xff1f;三、垃圾回收機制原理分析1、什么是引用計數&#xff1f;2、引用計數擴展閱讀&#xff1f;&#xff08;折疊&#xff09;Python的垃圾回收機制 引子: 我們定義變量會申…

安裝openssl-devel命令

centos&#xff1a; yum install openssl-devel ubuntu&#xff1a; sudo apt-get install openssl sudo apt-get install libssl-dev

阿里云天池 Python訓練營Task2: Python基礎練習:數據結構大匯總 學習筆記

本學習筆記為阿里云天池龍珠計劃Python訓練營的學習內容&#xff0c;學習鏈接為&#xff1a;https://tianchi.aliyun.com/specials/promotion/aicamppython?spm5176.22758685.J_6770933040.1.6f103da1tESyzu 目錄 一、學習知識點概要 二、學習內容 I.列表&#xff08;list…

windows文件與Linux文件互轉

使用命令 unix2dos filename dos2unix filename

1G.小a的排列(C++)

小a的排列&#xff08;C&#xff09; 點擊做題網站鏈接 題目描述 小a有一個長度為n的排列。定義一段區間是"萌"的&#xff0c;當且僅當把區間中各個數排序后相鄰元素的差為1現在他想知道包含數x,y的長度最小的"萌"區間的左右端點 也就是說&#xff0c;我們…