全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

shiro并发人数登录控制的实现代码

在某些项目中可能会遇到如每个账户同时只能有一个人登录或几个人同时登录,如果同时有多人登录:要么不让后者登录;要么踢出前者登录(强制退出)。比如spring security就直接提供了相应的功能;Shiro的话没有提供默认实现,不过可以很容易的在Shiro中加入这个功能。 

通过Shiro Filter机制扩展KickoutSessionControlFilter完成。 

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

kickoutSessionControlFilter用于控制并发登录人数的 

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获取相应的cache来缓存用户登录的会话;用于保存用户—会话之间的关系的;

sessionManager:用于根据会话ID,获取会话进行踢出操作的;

kickoutAfter:是否踢出后来登录的,默认是false;即后者登录的用户踢出前者登录的用户;

maxSession:同一个用户最大的会话数,默认1;比如2的意思是同一个用户允许最多同时两个人登录;

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拦截器进行并发登录控制。 

测试

此处因为maxSession=2,所以需要打开3个浏览器(需要不同的浏览器,如IE、Chrome、Firefox),分别访问http://localhost:8080/chapter18/进行登录;然后刷新第一次打开的浏览器,将会被强制退出,如显示下图: 

KickoutSessionControlFilter核心代码: 

Java代码  

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { 
 Subject subject = getSubject(request, response); 
 if(!subject.isAuthenticated() && !subject.isRemembered()) { 
 //如果没有登录,直接进行之后的流程 
 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); 
 } 
 //如果队列里没有此sessionId,且用户没有被踢出;放入队列 
 if(!deque.contains(sessionId) && session.getAttribute("kickout") == null) { 
 deque.push(sessionId); 
 } 
 //如果队列里的sessionId数超出最大会话数,开始踢人 
 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) { 
  //设置会话的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之间的关系;如果量比较大可以考虑如持久化到数据库/其他带持久化的Cache中;另外此处没有并发控制的同步实现,可以考虑根据用户名获取锁来控制,减少锁的粒度。

总结

以上所述是小编给大家介绍的shiro并发人数登录控制的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# shiro并发人数  # shiro  # 登录控制  # SpringBoot+Shiro学习之密码加密和登录失败次数限制示例  # springmvc集成shiro登录权限示例代码  # Java中SSM+Shiro系统登录验证码的实现方法  # shiro实现单点登录(一个用户同一时刻只能在一个地方登录)  # 使用Shiro实现登录成功后跳转到之前的页面  # Shiro 控制并发登录人数限制及登录踢出的实现代码  # 踢出  # 小编  # 重定向  # 有一  # 将会  # 最多  # 在此  # 很容易  # 有多  # 给大家  # 如果没有  # 来看看  # 用户登录  # 所述  # 给我留言  # 感谢大家  # 都走  # 疑问请  # 有任何  # 量比 


相关文章: 如何设置并定期更换建站之星安全管理员密码?  如何选择域名并搭建高效网站?  网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?  太原网站制作公司有哪些,网约车营运证查询官网?  开封网站制作公司,网络用语开封是什么意思?  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  定制建站方案优化指南:企业官网开发与建站费用解析  代刷网站制作软件,别人代刷火车票靠谱吗?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  大连网站制作公司哪家好一点,大连买房网站哪个好?  学校为何禁止电信移动建设网站?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  如何用景安虚拟主机手机版绑定域名建站?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  如何在橙子建站中快速调整背景颜色?  如何快速使用云服务器搭建个人网站?  如何在宝塔面板中修改默认建站目录?  MySQL查询结果复制到新表的方法(更新、插入)  如何设计高效校园网站?  建站主机CVM配置优化、SEO策略与性能提升指南    制作网站的软件免费下载,免费制作app哪个平台好?  如何在腾讯云服务器快速搭建个人网站?  宁波免费建站如何选择可靠模板与平台?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  官网建站费用明细查询_企业建站套餐价格及收费标准指南  红河网站制作公司,红河事业单位身份证如何上传?  如何通过商城自助建站源码实现零基础高效建站?  网站制作说明怎么写,简述网页设计的流程并说明原因?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  建站之星价格显示格式升级,你的预算足够吗?  Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  网站设计制作公司地址,网站建设比较好的公司都有哪些?  简单实现Android验证码  网站制作壁纸教程视频,电脑壁纸网站?  深圳网站制作平台,深圳市做网站好的公司有哪些?  如何快速搭建支持数据库操作的智能建站平台?  如何通过网站建站时间优化SEO与用户体验?  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  Swift中swift中的switch 语句  如何通过可视化优化提升建站效果?  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  如何在橙子建站上传落地页?操作指南详解  专业公司网站制作公司,用什么语言做企业网站比较好?  网站制作需要会哪些技术,建立一个网站要花费多少?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。