兩個問題
問題1:會話cookie通過URL傳遞
org.apache.shiro.session.UnknownSessionException: There is no session with id [2e9e317f-7575-4bb0-98c4-3e6e5d2578f5]
問題2:session找不到
https://localhost/login;JSESSIONID=eefe2007-a31b-492e-a56f-4d1fa8bd61c6
問題3:
出現場景:當進入登錄界面時(包括退出跳轉),就會出現創建了三個session會話。
會話創建:5d0cdb48-f58d-4855-b033-cd8b43def326
會話創建:7cdcbebe-0288-4f38-a35a-47e5d246b372
會話創建:8da8447a-e3e6-4240-9662-e43c83e58637
redis中會出現多余的session,這些多余的session無法轉換為user,我覺得是可能我的springboot集成了許多其他的框架,這些框架會去聯網來完成某些事情,或者登錄界面有問題,或者shiro配置有問題,反正暫時解決不了。所以也統計不了人數。對權限控制和登錄檢測啥的都沒有影響。
解決
問題1
在使用shiro之后,shiro的重定向跳轉,默認是帶有JSESSIONID的。
解決方案:
在sessionManager中添加
// 去掉shiro登錄時url里的JSESSIONID
sessionManager.setSessionIdUrlRewritingEnabled(false);
如果你發現defaultWebSessionManager.setSessionIdUrlRewritingEnabled(false);竟然報紅——沒有該方法。原因是1.3.2一下版本的shiro有bug,1.3.2以后的修復了這個URL重寫卻不可禁用的BUG
問題2
1):shiro的JSESSIONID 與Tomcat 、Jetty默認的JSESSIONID 沖突了。這時候需要改一下shiro對應的JSESSIONID:
2):你的session被刪除了,可能是你的過期時間太短了,或者其他地方有刪除的操作
1)的解決方案:
在shiro的DefaultWebSessionManager類中,默認Cookie名稱是JSESSIONID,這樣的話與servlet容器名沖突, 如jetty, tomcat等默認JSESSIONID, 當跳出shiro servlet時如error-page容器會為JSESSIONID重新分配值導致登錄會話丟失!
/**
* shiro session的管理
*/
public DefaultWebSessionManager sessionManager() {
...
...
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionIdCookie(sessionIdCookie());
}
/**
* 配置保存sessionId的cookie
* 注意:這里的cookie 不是上面的記住我 cookie 記住我需要一個cookie session管理 也需要自己的cookie
* @return
*/
@Bean("sessionIdCookie")
public SimpleCookie sessionIdCookie(){
SimpleCookie simpleCookie = new SimpleCookie("sid");
return simpleCookie;
}
這樣cookie的名字就由JSESSIONID改為sid
2)的解決方案
觸發事件:我登錄成功后再次去重復登錄,就會出現此錯誤
檢查自己代碼里有沒有刪除session的操作,我的就是這個原因
在自定義的Realm中我寫了一段代碼,負責單點登錄,用戶多個地方登錄,就會踢掉之前的session,實現單點登錄
//單用戶登錄,在線人數
//處理session
DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
//獲取當前已登錄的用戶session列表
Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
User temp;
int allUser=sessions.size();
for(Session session : sessions){
//清除該用戶以前登錄時保存的session,強制退出
Object attribute = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute == null) {
continue;
}
temp = (User) ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
if(userName.equals(temp.getUsername())) {
allUser--;
sessionManager.getSessionDAO().delete(session);
}
}
System.out.println("現在登錄人數為:"+allUser);
我重復登錄就會刪除session
很不錯的shiro錯誤的文章,不僅僅是解決問題,更是理解shiro
記一次蛋疼的tomcat、shiro自動生成的JESSIONID去除歷程..........
springboot整合shiro-session管理(六)
Apache Shiro去掉URL中的JSESSIONID
如何設置shiro保持登陸狀態?