shiro实现单点登录

本文介绍了如何使用Shiro框架实现单点登录功能,即同一账号在同一时刻只能在一个IP浏览器登录。通过Shiro的session管理机制,监听并移除已存在的同账号session,达到挤掉前一个登录用户的效果。配置了拦截URL规则,并展示了如何设置过滤器以确保所有/admin路径下的请求都经过特定的过滤逻辑来检查session状态。
摘要由CSDN通过智能技术生成

需求:实现同一个账号同一个时刻只能在一个IP浏览器登录,后者把前者挤掉线。
实现:通过shiro的session管理机制进行实现。
我的理解:shrio有一套sessionmanager的管理器,用来管理登录用户的session。不同的用户每次登录都会生成一个sessionid,保存在shrio框架中。我只需要实现根据登录用户的账号,判断正在登录的用户session是否已经存在于当前活跃的session列表中,如果存在的话,把那个session给删除,就可以成功实现将前一个登录的用户挤掉了。
这一段的逻辑代码是:

在自定义的ShiroJdbcRealm类中的doGetAuthenticationInfo--认证回调函数中加上:
        long loginOnTime = new Date().getTime();
        String tempSessionId = SecurityUtils.getSubject().getSession().getId().toString();//获取当前正在登录的用户的sessionID(已经登录了的,这是回调函数)
        logger.info("正在登陆---登陆用户{}",tempSessionId);
        AuthUserDetails userSession = null;
        int count = 0;
        if(authAccount != null){
            //获取在线的session,获取当前所有活跃的用户;包括正在登陆的这个用户
            Collection<Session> sessionCollection = sessionDAO.getActiveSessions();
            for (Session session : sessionCollection){
                // 获取simpleAuthenticationInfo的第一个参数的值
                if(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY) != null) {
                    //根据session build出一个subject
                    Subject subject = new Subject.Builder().session(session).buildSubject();
                    //循环遍历拿到已经登录的对象
                    userSession = (AuthUserDetails) subject.getPrincipal();
                    logger.info("缓存用户{}",userSession);
                    //判断已经登录的对象的code和现在正在登陆的code是否一致 ,这里的code用的是登录的账号
                    if (authAccount.getAuthUid().equals(userSession.getAuthUid())) {
                    	//同一个账户登录的时候,除了当前正在登录的用户,其他的session都要移除。
                    	if (session.getId()!=tempSessionId) {
							sessionDAO.delete(session);//从活跃的session列表中移除同一个账号的其他session,除了当前正在登录的session
							count++;
						}
                    }
                }
            }
        }
        System.out.println("---------------------------"+count);

由于每一个http请求都会生成一个sessionID,所以实际上会移除很多session,但是都是这个账号的,所以无所谓了。

其中sessionDAO.getActiveSessions();这一行是会获取到当前活跃的所有的session(也就是没有过期的包括当前正在登录的用户的session)

shiro自己的配置文件讲解:

spring-shiro.xml,这里面就是用来定义bean,然后加载到其他定义bean中当前属性值进行使用,这样的话就不用自己实例化了,在代码里可以直接使用。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"
	default-lazy-init="true">

	<description>Shiro安全配置</description>

	<!-- shiro cache using Redis 
	<bean id="shiroRedisManager" class="org.crazycake.shiro.RedisManager">
		<property name=&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值