真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

shiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼

在某些項(xiàng)目中可能會遇到如每個(gè)賬戶同時(shí)只能有一個(gè)人登錄或幾個(gè)人同時(shí)登錄,如果同時(shí)有多人登錄:要么不讓后者登錄;要么踢出前者登錄(強(qiáng)制退出)。比如spring security就直接提供了相應(yīng)的功能;Shiro的話沒有提供默認(rèn)實(shí)現(xiàn),不過可以很容易的在Shiro中加入這個(gè)功能。 

公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)公司推出鄂城免費(fèi)做網(wǎng)站回饋大家。

通過Shiro Filter機(jī)制擴(kuò)展KickoutSessionControlFilter完成。 

首先來看看如何配置使用(spring-config-shiro.xml)  

kickoutSessionControlFilter用于控制并發(fā)登錄人數(shù)的 

Java代碼  

 
  
  
  
  
  
 

cacheManager:使用cacheManager獲取相應(yīng)的cache來緩存用戶登錄的會話;用于保存用戶—會話之間的關(guān)系的;

sessionManager:用于根據(jù)會話ID,獲取會話進(jìn)行踢出操作的;

kickoutAfter:是否踢出后來登錄的,默認(rèn)是false;即后者登錄的用戶踢出前者登錄的用戶;

maxSession:同一個(gè)用戶最大的會話數(shù),默認(rèn)1;比如2的意思是同一個(gè)用戶允許最多同時(shí)兩個(gè)人登錄;

kickoutUrl:被踢出后重定向到的地址; 

shiroFilter配置 

Java代碼  

 
  
  
  
   
   
   
   
   
  
  
   
  /login = authc 
  /logout = logout 
  /authenticated = authc 
  /** = kickout,user,sysUser 
   
  
  

此處配置除了登錄等之外的地址都走kickout攔截器進(jìn)行并發(fā)登錄控制。 

測試

此處因?yàn)閙axSession=2,所以需要打開3個(gè)瀏覽器(需要不同的瀏覽器,如IE、Chrome、Firefox),分別訪問http://localhost:8080/chapter18/進(jìn)行登錄;然后刷新第一次打開的瀏覽器,將會被強(qiáng)制退出,如顯示下圖: 

shiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼

KickoutSessionControlFilter核心代碼: 

Java代碼  

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { 
 Subject subject = getSubject(request, response); 
 if(!subject.isAuthenticated() && !subject.isRemembered()) { 
 //如果沒有登錄,直接進(jìn)行之后的流程 
 return true; 
 } 
 Session session = subject.getSession(); 
 String username = (String) subject.getPrincipal(); 
 Serializable sessionId = session.getId(); 
 //TODO 同步控制 
 Deque deque = cache.get(username); 
 if(deque == null) { 
 deque = new LinkedList(); 
 cache.put(username, deque); 
 } 
 //如果隊(duì)列里沒有此sessionId,且用戶沒有被踢出;放入隊(duì)列 
 if(!deque.contains(sessionId) && session.getAttribute("kickout") == null) { 
 deque.push(sessionId); 
 } 
 //如果隊(duì)列里的sessionId數(shù)超出最大會話數(shù),開始踢人 
 while(deque.size() > maxSession) { 
 Serializable kickoutSessionId = null; 
 if(kickoutAfter) { //如果踢出后者 
  kickoutSessionId = deque.removeFirst(); 
 } else { //否則踢出前者 
  kickoutSessionId = deque.removeLast(); 
 } 
 try { 
  Session kickoutSession = 
  sessionManager.getSession(new DefaultSessionKey(kickoutSessionId)); 
  if(kickoutSession != null) { 
  //設(shè)置會話的kickout屬性表示踢出了 
  kickoutSession.setAttribute("kickout", true); 
  } 
 } catch (Exception e) {//ignore exception 
 } 
 } 
 //如果被踢出了,直接退出,重定向到踢出后的地址 
 if (session.getAttribute("kickout") != null) { 
 //會話被踢出了 
 try { 
  subject.logout(); 
 } catch (Exception e) { //ignore 
 } 
 saveRequest(request); 
 WebUtils.issueRedirect(request, response, kickoutUrl); 
 return false; 
 } 
 return true; 
} 

此處使用了Cache緩存用戶名—會話id之間的關(guān)系;如果量比較大可以考慮如持久化到數(shù)據(jù)庫/其他帶持久化的Cache中;另外此處沒有并發(fā)控制的同步實(shí)現(xiàn),可以考慮根據(jù)用戶名獲取鎖來控制,減少鎖的粒度。

總結(jié)

以上所述是小編給大家介紹的shiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對創(chuàng)新互聯(lián)網(wǎng)站的支持!


當(dāng)前題目:shiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼
當(dāng)前URL:http://weahome.cn/article/gsogco.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部