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