Apache shiro如何实现一个账户同一时间只能在一个浏览器登录

   日期:2020-08-22     浏览:256    评论:0    
核心提示:Apache shiro如何实现一个账户同一时间只能在一个浏览器登录限制登录功能,用shiro安全框架管理session会话shiro-会话管理:shiro-会话相关API:限制登录功能,用shiro安全框架管理session会话效果就是 不让用户进行第二次登录,除非第一次登陆超过5分钟进行任何操作,才可以登录话不多说上代码//Controller层如下:@Resource private SessionDAO sessionDao;@ResponseBody

会话

即用户访问应用时保持的连接关系,通过会话应用可以在多次访问中识别出当前的用户是谁,还可以在交互中保存数据。

限制登录功能,用shiro安全框架管理session会话

效果就是 不让同一个账户通过其他浏览器进行二次登录,除非在已登陆页面超过5分钟未进行任何操作,才可以再次登录

话不多说上代码

//Controller层如下:
@Resource private SessionDAO sessionDao;

@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponsePojo login(String username, String password, String captcha)throws IOException {
	//验证码校验省略。。。
	//用户名密码非空校验省略。。。
	try{
    	Subject subject = ShiroUtils.getSubject();

        //获取当前已登录的用户session列表
        Collection<Session> sessions = sessionDao.getActiveSessions();
        for (Session session : sessions) {
            Subject s = new Subject.Builder().session(session).buildSubject();
            //判断是否已通过认证
            if (s.isAuthenticated()) {
                SysUser u = (SysUser) s.getPrincipal();
                //sessionId不同 且 登录用户名相同——>进行登录限制
                if (u!=null && username.equalsIgnoreCase(u.getUsername()) && 
                	!session.getId().equals(subject.getSession().getId())) {
                    //获取目前未操作时长
                    long timeOut = (new Date().getTime() - session.getLastAccessTime().getTime());
                    if (timeOut>300000){
                        //移除5分钟内无操作的会话
                        sessionDao.delete(session);
                    }else {
                        return ResponsePojo.error("账号已登录,请先从其他平台退出登录;或者请"+
                        	((300000 - timeOut)/60000+1)+"分钟后重试");
                    }
                }
            }
        }
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //登录认证
        subject.login(token);
    }catch (Exception e) {
    	//其他异常省略。。。
		msg = e.getMessage();
		return ResponsePojo.error(msg);
	}
}

shiro-会话管理:

shiro自己实现了一套session管理体系可以在不借助任何web容器或servlet的情况下使用session。
SessionManager(session管理器)、SessionDAO(实现session的增删改查)

所以还要配置shiro.xml

<!-- 实现session的增删改查 -->
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
</bean>

<!-- session管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
	<!-- 设置session过期时间为12小时(单位:毫秒),默认为30分钟 -->
	<property name="globalSessionTimeout" value="43200000"></property>
	<property name="sessionValidationSchedulerEnabled" value="true"></property>
	<property name="sessionDAO" ref="sessionDAO"/>
</bean>

shiro-会话相关API:

Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();

拿到session之后,就可以调用以下API(省略一部分。。。)

返回值 方法名 描述
Serializable getId() 获取session的唯一id
Object getAttribute(Object key) 根据key标识返回绑定到session的对象
Date getLastAccessTime() 获取最后的访问时间
Date getStartTimestamp() 获取session的启动时间

我这里用到了就是getLastAccessTime()这个获取最后访问时间的方法,
判断当前时间距离最后一次访问时间 :
如果大于5分钟 说明前者登录有5分钟以上未操作页面,清除此session以后,后者就可以进行登录;
如果小于5分钟 说明前者5分钟内有操作过页面,提示后者可以先进行退出再登陆,或者等几分钟再登陆;

//移除5分钟内无操作的会话 目的就是 防止用户非正常退出,直接关闭浏览器或断电,session未过期或未清除
sessionDao.delete(session);

不足之处请指出
转发引用请注明原文地址

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服