首先,我们要说明一下,本技术点的开发背景是shiro与springMvc结合环境下的开发方式。

  由于shiro把用户登录后的信息都存在了自己封装的session中,所以要实现单一地址登录,我们需要关注到shiro的 session操作。技术实现步骤如下:

一、在shiro的xml配置文件中

1、加入sessionManager配置

    <!-- shiro结合Session会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时长,单位毫秒 1小时: 3600000, 站点设置以 6小时 为主:21600000 -->
<!-- 设置全局会话超时时间,默认30分钟,即如果30分钟内没有访问会话将过期 1800000 -->
<property name="globalSessionTimeout" value="1800000"/>
<!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
<!-- 是否开启会话验证器,默认是开启的 -->
<property name="sessionValidationSchedulerEnabled" value="true"/>
</bean>

2、在安全管理器中注入session管理器

<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
<!-- 注入session管理器 -->
<property name="sessionManager" ref="sessionManager" />
</bean>

Ps:以上操作针对没有将session管理器注入到安全管理器的同学。因为我们之后需要用到sessionManager,如果没有注入,在运行时会报‘’ServletContainerSessionManager cannot be cast to org.apache.shiro.web.session.mgt.DefaultWebSessionManager‘’错误;

二、在登录的controller中判断重复session,并把他们关闭

1、在controller中写入如下的方法,用于根据当前登录用户,筛选出已登录session中重复登录的信息集合

  /**
*
* @param currentUser 当前登录用户的shiro认证信息
* @return 重复登录的用户Session(shiro格式)
* Description: 遍历同一个账户的现有的session用户信息并将重复的登录缓存信息输出
* @author mylydg
* @date
*/
private List<Session> getLoginedSession(Subject currentUser) {
//获得当前登录用户的全部session
Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils
.getSecurityManager()).getSessionManager()).getSessionDAO()
.getActiveSessions();
List<Session> loginedList = new ArrayList<Session>();
Sys_User loginUser = (Sys_User) currentUser.getPrincipal();//获得当前用户信息
for (Session session : list) { Subject s = new Subject.Builder().session(session).buildSubject(); if (s.isAuthenticated()) {
Sys_User user = (Sys_User) s.getPrincipal(); if (user.getLogin_Name().equalsIgnoreCase(loginUser.getLogin_Name())) {
if (!session.getId().equals(
currentUser.getSession().getId())) {
loginedList.add(session);//把除当前登录用户的其他的同名用户session信息加入集合
}
}
}
}
return loginedList;
}

2、在认证登录方法中关闭重复认证的session

@RequestMapping("/login")
public String login(String username,String password,Model model) {
//获取shiro的控制类Subject
Subject subject = SecurityUtils.getSubject();
//获取身份信息
Sys_User cacheUser =(Sys_User)subject.getPrincipal();
if(cacheUser!=null)
{
model.addAttribute("user", cacheUser);
return "sys/user/main";
}
if(username == null) {
return "sys/user/login";
}
//创建一个用于验证用户名和密码的token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Sys_User user;
try {
//验证用户名密码
subject.login(token);
//----------------------------关键代码 star--------------------------------------------
//检查当前登录用户信息,将存在重复登录用户信息筛选出来
List<Session> loginedList = getLoginedSession(subject);
for (Session session : loginedList) {
session.stop();//关闭重复用户登录信息缓存
}
//----------------------------关键代码 end--------------------------------------------
//这个方法是获取shiro里面的登录信息,如果reaml里面传入的是对象,这里就是
//对象,如果是字符串,这里就是字符串,按照相应的格式转换使用即可
Object o = subject.getPrincipal();
user = (Sys_User)o;
System.out.println(user.getLogin_Name()+" "+user.getPassword());
model.addAttribute("user", user);
} catch (UnknownAccountException e) {
model.addAttribute("errormessage", "用户名错误!");
System.out.println("userName 用户名错误!");
return "sys/user/login";
} catch (IncorrectCredentialsException e) {
model.addAttribute("errormessage", "密码错误!");
System.out.println("passwd 密码错误");
return "sys/user/login";
}

再次运行系统后,功能实现~

关于shiro安全框架实现同一用户同一时刻仅可在一个地址登录的技术实现的更多相关文章

  1. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

  2. (十二)整合 Shiro 框架,实现用户权限管理

    整合 Shiro 框架,实现用户权限管理 1.Shiro简介 1.1 基础概念 1.2 核心角色 1.3 核心理念 2.SpringBoot整合Shiro 2.1 核心依赖 2.2 Shiro核心配置 ...

  3. Shiro安全框架入门篇(登录验证实例详解与源码)

    转载自http://blog.csdn.net/u013142781 一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和J ...

  4. Apache Shiro权限框架在SpringMVC+Hibernate中的应用

    在做网站开发中,用户权限必须要考虑的,权限这个东西很重要,它规定了用户在使用中能进行哪 些操作,和不能进行哪些操作:我们完全可以使用过滤器来进行权限的操作,但是有了权限框架之后,使用起来会非常的方便, ...

  5. shiro安全框架

    原文:http://blog.csdn.net/boonya/article/details/8233303 可能大家早先会见过 J-security,这个是 Shiro 的前身.在 2009 年 3 ...

  6. Shiro 权限框架使用总结

    我们首先了解下什么是shiro ,Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨 ...

  7. shiro权限框架

    权限的组成部分:用户 资源 角色 权限 数据库关系表设计是根据自己项目需求设计的 account表role表(id,rolename)account_role(id,aid,rid)permissio ...

  8. shiro权限框架(一)

    不知不觉接触shiro安全框架都快三个月了,这中间配合项目开发踩过无数的坑.现在回想总结下,也算是一种积累,一种分享.中间有不够完美的地方或者不好的地方,希望大家指出来能一起交流.在这里谢谢开涛老师的 ...

  9. Shiro安全框架【快速入门】就这一篇!

    Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...

随机推荐

  1. MAC--NPAPI学习(一)简要介绍NPAPI的函数

    NPAPI是浏览器与插件交互的接口,下面先简要介绍一下NPAPI的函数: Mach-o entry points NPError NP_Initialize(NPNetscapeFuncs* brow ...

  2. 学习笔记 Optional

    今天学习到的一种新的防止空指针的方法下面是我自己写的一个例子:节省空间,bean的get set 省略... /** * 类目 * @author 唐 * @date 2018/5/6 17:45 * ...

  3. python学习6---排序问题

    1.对列表排序 一维列表: sorted():可用于任何可迭代对象,如数组.列表.字典等. sort():list.sort()返回None,这是因为sort在函数内部修改了list的值,当再次访问l ...

  4. UVa 712

    这个题根本不用建树,因为是完全二叉树,可以把这个想成二进制.对于根是二进制数的首位,之后依次类推.到最后的叶子节点就是从0到pow(2,n)-1. 关键在于在第一次输入的不是按照x1,x2,x3,x4 ...

  5. 20155219付颖卓《网络攻防》Exp4 恶意代码分析

    一.基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控. 可以用window7自带的schtasks ...

  6. adb 安装安卓包

    1.搭建安卓环境,或者下载安装ADB工具 2.adb version检查是否安装成功 3.用数据线连上手机,并在手机中打开USB调试模式,使用adb devices 查看链接的设备 这样表示成功连接上 ...

  7. maya权重拷贝一对一,一对多

    是不是有时候盔甲很多很碎头很大,用代理一个个拷贝很麻烦吧 用下面代码直接运行进行一对多或者一对一拷贝 第一个先选择参考物体,加选其他一堆有的没的有权重或没权重的物体执行一键拷贝,就可以啦 以下是源码送 ...

  8. springAop注解式Demo

    package AnnoAspect.Aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.anno ...

  9. Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布

    一.Nginx安装(基于CentOS 6.5) 1.yum命令安装 yum install nginx –y(若不能安装,执行命令yum install epel-release) 2. 启动.停止和 ...

  10. EXCEL中,如何引用一个单元格中的数据,作为另一个单元格内容中的一部分?

    https://zhidao.baidu.com/question/230715654.html 假设单元格A1值是8(该值由函数计算得出),我要在单元格B1中引用A1的值,但只是作为B1单元格内容中 ...