Shiro并发登录人数控制遇到的问题和解决
shiro并發登錄人數控制遇到的問題和解決
- 問題1:KickoutSessionControlFilter不起作用
- 問題2:KickoutSessionControlFilter中cache為null空指針異常
- 問題3:服務器重啟后首頁訪問:subject.getPrincipal()報ClassCastException異常
- 系統環境
- 參考資料
問題1:KickoutSessionControlFilter不起作用
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {}中設置:
{
…
filters.put(“kickout”, new KickoutSessionControlFilter());
…
filterMap.put("/**", “kickout”);
}
結果:KickoutSessionControlFilter不起作用。
進一步查看代碼:
查看代碼行:shiroFilter.setFilterChainDefinitionMap(filterMap);
setFilterChainDefinitionMap點進去:
public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) {...filterChainDefinitionMap.put("/**", "user");super.setFilterChainDefinitionMap(filterChainDefinitionMap);... }分析:
filterMap.put("/**", "kickout");和
filterChainDefinitionMap.put("/**", "user");操作的是同一個對象,
filterChainDefinitionMap是一個Map,
key一樣,put會覆蓋掉前面的值。
解決:
改
問題2:KickoutSessionControlFilter中cache為null空指針異常
public class KickoutSessionControlFilter extends AccessControlFilter {private Cache<String, Deque<Serializable>> cache;...@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {...Deque<Serializable> deque = cache.get(username);...deque = new LinkedList<Serializable>();cache.put(username, deque);...} }查看:ShiroConfig.java中session管理器SessionManager
@Beanpublic SessionManager sessionManager(GlobalProperties globalProperties){DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setSessionValidationSchedulerEnabled(true);sessionManager.setSessionIdUrlRewritingEnabled(false);sessionManager.setDeleteInvalidSessions(true);if (globalProperties.isRedisSessionDao()) {// 開啟redis會話管理器sessionManager.setSessionFactory(new UserSessionFactory());sessionManager.setSessionDAO(new UserSessionDAO());List<SessionListener> sessionListeners = new ArrayList<>();sessionListeners.add(new UserSessionListener());sessionManager.setSessionListeners(sessionListeners);}return sessionManager;}發現:框架沒有配置CacheManager,有配置redis會話管理,改用RedisCacheManager。
解決:
問題3:服務器重啟后首頁訪問:subject.getPrincipal()報ClassCastException異常
@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {Subject subject = getSubject(request, response);if(!subject.isAuthenticated() && !subject.isRemembered()) {//如果沒有登錄,直接進行之后的流程return true;}Session session = subject.getSession();SysUserEntity user = (SysUserEntity) subject.getPrincipal();username= user.getUsername();... }一番打端點分析:
用戶登陸狀態下,服務器重啟后:
subject.isAuthenticated()仍然為true。“//如果沒有登錄,直接進行之后的流程”該步驟不能進入,未return true,繼續后續執行。
且session仍然在,未失效。
(SysUserEntity) subject.getPrincipal();
強轉報異常,原因不明。
暫時解決方法:try捕獲ClassCastException時調用subject.logout();登出。定向到首頁。
try {SysUserEntity user = (SysUserEntity) subject.getPrincipal();username= user.getUsername();} catch (ClassCastException cce) {//服務器重啟后,session仍然在,但subject.getPrincipal會有強轉異常try {subject.logout();} catch (Exception e) { //ignore}saveRequest(request);httpServletRequest.setAttribute("errorMsg", "登錄超時,請重新登錄");httpServletRequest.getRequestDispatcher("/login").forward(request, response);return false;}系統環境
springboot
參考資料
https://blog.csdn.net/qq_33556185/article/details/51744004
https://www.w3cschool.cn/shiro/epht1ifg.html
總結
以上是生活随笔為你收集整理的Shiro并发登录人数控制遇到的问题和解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NuGet Error:Unable t
- 下一篇: IDEA写sql语句的时候没有提示信息的