第24章 在线会话管理

有时候需要显示当前在线人数、当前在线用户,有时候可能需要强制某个用户下线等,此时就需要获取相应的在线用户并进行一些操作,本章基于《第十六章 综合实例》代码构建。

会话控制器

@RequiresPermissions("session:*")

@Controller

@RequestMapping("/sessions")

public class SessionController {

@Autowired

private SessionDAO sessionDAO;

@RequestMapping()

public String list(Model model) {

Collection<Session> sessions = sessionDAO.getActiveSessions();

model.addAttribute("sessions", sessions);

model.addAttribute("sesessionCount", sessions.size());

return "sessions/list";

}

@RequestMapping("/{sessionId}/forceLogout")

public String forceLogout(@PathVariable("sessionId") String sessionId,

RedirectAttributes redirectAttributes) {

try {

Session session = sessionDAO.readSession(sessionId);

if(session != null) {

session.setAttribute(

Constants.SESSION_FORCE_LOGOUT_KEY, Boolean.TRUE);

}

} catch (Exception e) {/*ignore*/}

redirectAttributes.addFlashAttribute("msg", "强制退出成功!");

return "redirect:/sessions";

}

}

1、list方法:提供了展示所有在线会话列表,通过sessionDAO.getActiveSessions()获取所有在线的会话。

2、forceLogout方法:强制退出某一个会话,此处只在指定会话中设置Constants.SESSION_FORCE_LOGOUT_KEY属性,之后通过ForceLogoutFilter判断并进行强制退出。

此处展示会话列表的缺点是:sessionDAO.getActiveSessions()提供了获取所有活跃会话集合,如果做一般企业级应用问题不大,因为在线用户不多;但是如果应用的在线用户非常多,此种方法就不适合了,解决方案就是分页获取:

Page<Session> getActiveSessions(int pageNumber, int pageSize);

Page对象除了包含pageNumber、pageSize属性之外,还包含totalSessions(总会话数)、Collection<Session> (当前页的会话)。

分页获取时,如果是MySQL这种关系数据库存储会话比较好办,如果使用Redis这种数据库可以考虑这样存储:

session.id=会话序列化数据

session.ids=会话id Set列表(接着可以使用LLEN获取长度,LRANGE分页获取) 会话创建时(如sessionId=123),那么redis命令如下所示:

SET session.123 "Session序列化数据"

LPUSH session.ids 123

会话删除时(如sessionId=123),那么redis命令如下所示:

DEL session.123

LREM session.ids 123

获取总活跃会话:

LLEN session.ids

分页获取活跃会话:

LRANGE key 0 10 #获取到会话ID

MGET session.1 session.2…… #根据第一条命令获取的会话ID获取会话数据

ForceLogoutFilter

public class ForceLogoutFilter extends AccessControlFilter {

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

Session session = getSubject(request, response).getSession(false);

if(session == null) {

return true;

}

return session.getAttribute(Constants.SESSION_FORCE_LOGOUT_KEY) == null;

}

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

try {

getSubject(request, response).logout();//强制退出

} catch (Exception e) {/*ignore exception*/}

String loginUrl = getLoginUrl() + (getLoginUrl().contains("?") ? "&" : "?") + "forceLogout=1";

WebUtils.issueRedirect(request, response, loginUrl);

return false;

}

}

强制退出拦截器,如果用户会话中存在Constants.SESSION_FORCE_LOGOUT_KEY属性,表示被管理员强制退出了;然后调用Subject.logout()退出,且重定向到登录页面(自动拼上fourceLogout请求参数)。

登录控制器

在LoginController类的showLoginForm方法中最后添加如下代码:

if(req.getParameter("forceLogout") != null) {

model.addAttribute("error", "您已经被管理员强制退出,请重新登录");

}

即如果有请求参数forceLogout表示是管理员强制退出的,在界面上显示相应的信息。

Shiro配置spring-config-shiro.xml

和之前的唯一区别是在shiroFilter中的filterChainDefinitions拦截器链定义中添加了forceLogout拦截器:

/** = forceLogout,user,sysUser

测试

1、首先输入http://localhost:8080/chapter24/跳转到登录页面输入admin/123456登录;

2、登录成功后,点击菜单的“会话管理”,可以看到当前在线会话列表:

3、点击“强制退出”按钮,会话相应的用户再点击界面的话会看到如下界面,表示已经被强制退出了:

另外可参考我的ES中的在线会话管理功能:UserOnlineController.java,其使用数据库存储会话,并分页获取在线会话。

时间: 2024-10-28 02:37:29

第24章 在线会话管理的相关文章

Shiro学习(24)在线回话管理

有时候需要显示当前在线人数.当前在线用户,有时候可能需要强制某个用户下线等:此时就需要获取相应的在线用户并进行一些操作. 本章基于<第十六章 综合实例>代码构建. 会话控制器 Java代码   @RequiresPermissions("session:*") @Controller @RequestMapping("/sessions") public class SessionController { @Autowired private Sessi

在线会话管理

有时候需要显示当前在线人数.当前在线用户,有时候可能需要强制某个用户下线等:此时就需要获取相应的在线用户并进行一些操作. 会话控制器 @RequiresPermissions("session:*") @Controller @RequestMapping("/sessions") public class SessionController { @Autowired private SessionDAO sessionDAO; @RequestMapping()

第二章 Session会话管理

采用网址重写的缺点: 在有些Web浏览器中,URL限制为2000个字符. 仅当有链接要插入值时,值才能转换成后面的资源.此外,要把值添加到静态页面的链接中,可不是一件容易的事情. 网址重写必须在服务器端有效.所有的链接都必须带有值,这样可能出现一个问题,即一个页面中可能会有许多个链接. 某些字符,例如空格.&符号及问号都必须进行编码. 添加到URL中的信息是明显可见的,这种情况有时可不是我们所期待的. 网址重写案例设计: 1.访问top10,返回一个页面,该页面中的每个按钮的url都被重写了,加

《白帽子讲WEB安全》学习笔记之第9章 认证与会话管理

第9章 认证与会话管理 9.1 who am i? 认证包含了身份和身份认证两层含义. q  身份-我是谁? q  身份认证-这就是我. 认证的目的就是为了认出用户是谁?而授权的目的是为了决定用户能够做什么. 认证实际上就是一个验证凭证的过程. 9.2 密码的那些事儿 一般为了安全与用户体验性,采用"双因素"验证的比较多,例如支付中的密码和手机动态密钥. 我认为在用户注册的时候应该检测一下用户使用的是否是弱密码.这就代表着我们需要在系统中建立一套"弱密码表",弱密码

会话管理

一.会话管理的基本原理 web应用程序的请求与响应是基于HTTP,为无状态的通信协议,服务器不会记得这次请求和下次请求的关系,如购物车,用户可能在多个购物网页之间采购商品,web应用程序必须有个方式来得知用户在这些网页中采购了哪些商品,这种记得此次请求与之后请求间关系的方式,就称为会话管理(Session Management). 1.使用隐藏域 隐藏域就是主动告知服务器多次请求间必要信息的方式之一.以问卷作答的为例,上一页的问卷答案,可以用隐藏域的方式放在下一页的窗体中,这样发送下一页窗体,就

(转)web会话管理方式

阅读目录 1. 基于server端session的管理 2. cookie-based的管理方式 3. token-based的管理方式 4. 安全问题 5. 总结 http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于我们的应用来说,我们是靠用户来管理,而不是靠客户端.所以对我们的应用而言,它是需要有状态管理的,以便服务端能够准确的知道http请求是哪个用户发起的,从而判断他是否有权限继续这个请求.这

会话管理(Cookie/Session技术)

什么是会话:用户打开浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称为一个会话: 会话过程需要解决的问题:每个用户在使用浏览器与服务器进行会话的过程中,都可能会产生一些数据,这些输入如何来进行保存?比如用户在购物网站浏览的商品记录,用户添加购物车的记录等等这些信息如何进行存储?在程序中会话跟踪是一件非常重要的事情,一个用户的所有请求操作都应该属于同一个会话,而另一个人的所有请求操作应该属于另一个人,二者不能混淆!当想到需要在保存数据时,我们首先肯定会想到使用域对象

第十章 会话管理——《跟我学Shiro》

Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如web容器tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理.会话事件监听.会话存储/持久化.容器无关的集群.失效/过期支持.对Web的透明支持.SSO单点登录的支持等特性.即直接使用Shiro的会话管理可以直接替换如Web容器的会话管理. 会话 所谓会话,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据.如访问一些网站时登录成功后,网站可以记住用

高项3.7日第一次课,第一章信息化基础知识与第二章信息系统服务管理梳理

第一章 信息化的基础知识 1.国家信息化体系要素: 主要包括6要素,信息技术应用(龙头).信息资源(关键).信息网络(必要手段).信息技术产业(基础).信息化人才(成功之本).信息化法规政策和规范(保障). 2.电子政务: 电子政务建设的指导原则: (1)统一规划,加强领导. (2)需求主导,突出重点. (3)统一规划,拉动产业. (4)统一标准,保障安全. 主要任务: (1)电子政务网络由政务内网和政务外网构成,两网之间物理隔离,政务外网与互联网之间逻辑隔离.政务内网主要是副省级以上政务部门的