欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2017年09月20日 10:14:19   作者:動(dòng)力節(jié)點(diǎn)  
在做項(xiàng)目中遇到這樣的需求要求每個(gè)賬戶同時(shí)只能有一個(gè)人登錄或幾個(gè)人同時(shí)登錄,如果是同時(shí)登錄的多人,要么不讓后者登錄,要么踢出前者登錄,怎么實(shí)現(xiàn)這樣的功能呢?下面小編給大家?guī)砹藄hiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼,一起看看吧

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

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

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

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

Java代碼  

<bean id="kickoutSessionControlFilter" 
class="com.github.zhangkaitao.shiro.chapter18.web.shiro.filter.KickoutSessionControlFilter"> 
 <property name="cacheManager" ref="cacheManager"/> 
 <property name="sessionManager" ref="sessionManager"/> 
 <property name="kickoutAfter" value="false"/> 
 <property name="maxSession" value="2"/> 
 <property name="kickoutUrl" value="/login?kickout=1"/> 
</bean> 

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

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

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

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

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

shiroFilter配置 

Java代碼  

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
 <property name="securityManager" ref="securityManager"/> 
 <property name="loginUrl" value="/login"/> 
 <property name="filters"> 
  <util:map> 
  <entry key="authc" value-ref="formAuthenticationFilter"/> 
  <entry key="sysUser" value-ref="sysUserFilter"/> 
  <entry key="kickout" value-ref="kickoutSessionControlFilter"/> 
  </util:map> 
 </property> 
 <property name="filterChainDefinitions"> 
  <value> 
  /login = authc 
  /logout = logout 
  /authenticated = authc 
  /** = kickout,user,sysUser 
  </value> 
 </property> 
 </bean> 

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

測(cè)試

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

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<Serializable> deque = cache.get(username); 
 if(deque == null) { 
 deque = new LinkedList<Serializable>(); 
 cache.put(username, deque); 
 } 
 //如果隊(duì)列里沒有此sessionId,且用戶沒有被踢出;放入隊(duì)列 
 if(!deque.contains(sessionId) && session.getAttribute("kickout") == null) { 
 deque.push(sessionId); 
 } 
 //如果隊(duì)列里的sessionId數(shù)超出最大會(huì)話數(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è)置會(huì)話的kickout屬性表示踢出了 
  kickoutSession.setAttribute("kickout", true); 
  } 
 } catch (Exception e) {//ignore exception 
 } 
 } 
 //如果被踢出了,直接退出,重定向到踢出后的地址 
 if (session.getAttribute("kickout") != null) { 
 //會(huì)話被踢出了 
 try { 
  subject.logout(); 
 } catch (Exception e) { //ignore 
 } 
 saveRequest(request); 
 WebUtils.issueRedirect(request, response, kickoutUrl); 
 return false; 
 } 
 return true; 
} 

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

總結(jié)

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

相關(guān)文章

  • java中Spring Security的實(shí)例詳解

    java中Spring Security的實(shí)例詳解

    這篇文章主要介紹了java中Spring Security的實(shí)例詳解的相關(guān)資料,spring security是一個(gè)多方面的安全認(rèn)證框架,提供了基于JavaEE規(guī)范的完整的安全認(rèn)證解決方案,需要的朋友可以參考下
    2017-09-09
  • Java中初始化List的5種方法示例

    Java中初始化List的5種方法示例

    這篇文章主要給大家介紹了關(guān)于Java中初始化List的5種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • MDC在多線程中的使用方式

    MDC在多線程中的使用方式

    這篇文章主要介紹了MDC在多線程中的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 解決引入Redisson可能會(huì)出現(xiàn)項(xiàng)目啟動(dòng)失敗的問題

    解決引入Redisson可能會(huì)出現(xiàn)項(xiàng)目啟動(dòng)失敗的問題

    這篇文章主要介紹了解決引入Redisson可能會(huì)出現(xiàn)項(xiàng)目啟動(dòng)失敗的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java多線程 ThreadLocal原理解析

    Java多線程 ThreadLocal原理解析

    這篇文章主要介紹了Java多線程 ThreadLocal原理,ThreadLoal 變量,線程局部變量,同一個(gè) ThreadLocal 所包含的對(duì)象,在不同的 Thread 中有不同的副本,下面文章也是圍繞Java多線程 ThreadLocal展開內(nèi)容,需要的朋友可以參考一下
    2021-10-10
  • Java數(shù)據(jù)結(jié)構(gòu)之線段樹的原理與實(shí)現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之線段樹的原理與實(shí)現(xiàn)

    線段樹是一種二叉搜索樹,是用來維護(hù)區(qū)間信息的數(shù)據(jù)結(jié)構(gòu)。本文將利用示例詳細(xì)講講Java數(shù)據(jù)結(jié)構(gòu)中線段樹的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-06-06
  • mybatis和mybatisplus批量插入問題示例詳解

    mybatis和mybatisplus批量插入問題示例詳解

    最近在處理一個(gè)功能的時(shí)候,需要批量插入數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于mybatis和mybatisplus批量插入問題的相關(guān)資料,文中通過實(shí)例代碼介紹非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • springboot-curd基于mybatis項(xiàng)目搭建

    springboot-curd基于mybatis項(xiàng)目搭建

    這篇文章主要介紹了springboot-curd基于mybatis項(xiàng)目搭建,圍繞相關(guān)資料展開詳細(xì)內(nèi)容,希望對(duì)正在學(xué)習(xí)的你有所幫助,需要的小伙伴也可以參考一下
    2022-01-01
  • 基于@Valid和@Validated驗(yàn)證List集合的踩坑記錄

    基于@Valid和@Validated驗(yàn)證List集合的踩坑記錄

    這篇文章主要介紹了基于@Valid和@Validated驗(yàn)證List集合的踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法

    idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法

    這篇文章主要介紹了idea導(dǎo)入項(xiàng)目不顯示maven側(cè)邊欄的問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論