学习Acegi应用到实际项目中(4)
此节介绍:ConcurrentSessionFilter。
在Acegi 1.x版本中,控制并发HttpSession和Remember-Me认证服务不能够同时启用,它们之间存在冲突问题。
在一些应用场合,企业可能需要限制同一帐号在同一时间登录到同一Web应用的次数,即控制并发HttpSession的数量。比如,在同一时间,只允许javaee/password用户在服务器存在一个或若干个活动HttpSession。Acegi内置了HttpSession的并发控制支持,为我们提供了方便。为了启用这一企业特性,开发者必须完成如下几方面的配置。
1、将concurrentSessionFilter添加到filterChainProxy中
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=concurrentSessionFilter,httpSessionContextIntegrationFilter,
logoutFilter,authenticationProcessingFilter,
anonymousProcessingFilter,exceptionTranslationFilter,
filterInvocationInterceptor
</value>
</property>
</bean>
2、配置ConcurrentSessionFilter
控制并发HttpSession的过滤器,concurrentSessionFilter暴露了sessionRegistry和expiredUrl属性,sessionRegistry引用一个HttpSession注册器,这一注册器动态维护了登录到这一Web应用的所有HttpSession信息。
ConcurrentSessionFilter起到两个作用:
第一、对每个请求, 它都会调用org.acegisecurity.concurrent.SessionRegistry.refreshLastRequest(String)方法,这样保证所有已注册的会话总是有正确的最后修改时间。
第二、它会从SessionRegistry为每个请求返回org.acegisecurity.concurrent.SessionInformation会话信息,并且检查session是否已标记为过期。如果已标记为过期,那么该session将会被invalidate()掉。
<bean id="concurrentSessionFilter" class="org.acegisecurity.concurrent.ConcurrentSessionFilter">
<!-- 每次HttpSession开始或者结束的时候,web.xml中的HttpSessionEventPublisher都会发布一个 ApplicationEvent事件到Spring的ApplicationContext。
这是至关重要的,因为这个机制允许在session结束的时候,SessionRegistryImpl会得到通知。
这解释了为什么我们需要在ConcurrentSessionFilter中指向 SessionRegistryImpl的实例。-->
<property name="sessionRegistry" ref="sessionRegistry"></property>
<!-- 如果concurrentSessionController的exceptionIfMaximumExceeded属性设置为true,那么一旦并发HttpSession数量超过限额,将会重定向到expiredUrl指定的路径 -->
<property name="expiredUrl">
<value>/concurrentError.jsp</value>
</property>
</bean>
<!-- 注意,我们的程序一般并不用直接与SessionRegistryImpl打交道,你只需在Spring的配置文件定义一个Bean就行了 -->
<bean id="sessionRegistry"
class="org.acegisecurity.concurrent.SessionRegistryImpl">
</bean>
3、配置HttpSessionEventPublisher
SessionRegistry的实现类是SessionRegistryImpl,SessionRegistryImpl实现了ApplicationListener,而且它会负责应对HttpSessionDestroyedEvent事件。一旦SessionRegistryImpl接收到HttpSessionDestroyedEvent事件,则它会把触发这一事件的HttpSession的相关信息从当前注册器中清除掉。因此,HttpSessionEventPublisher的配置工作显得格外重要。在web.xml中添加
<listener>
<listener-class>
org.acegisecurity.ui.session.HttpSessionEventPublisher
</listener-class>
</listener>
4、配置concurrentSessionController
并发HttpSession控制器, concurrentSessionController只需要一个sessionRegistry实例的属性,但它应用时还使用了maximumSessions属性,把它赋值为1。在ConcurrentSessionControllerImpl的源代码中,这个值初始值其实也是1。
它的用法和用处是如下:
(1)可以给它赋值-1,那么将不会限制并发登录。
(2)可以给它赋大于0值,这个数字限制相同用户名同时成功并发登录同一个web应用的次数。
注意:不可以给它赋值为0,这是不允许的。
例如,如果这个值是3,那么用户名为javaee的用户可以同时在3个地点同时成功登录进web应用,只要密码正确。
maximumSessions:允许用户创建的最大并发HttpSession数量。
exceptionIfMaximumExceeded:一旦并发HttpSession数量超过限额,是否抛出异常。
<bean id="concurrentSessionController"
class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="maximumSessions" value="1"></property>
<property name="sessionRegistry" ref="sessionRegistry"></property>
<!--
一般设置为false. 为true时, 如果已有一个该用户登录了, 那么在另一个地方登录该用户将抛出异常
如果设置为false, 那么, 如果已有一个该用户登录了系统, 那么在另一个地方也可以登录, 登录后前者会被逼退出系统
-->
<property name="exceptionIfMaximumExceeded" value="true"></property>
</bean> <!--一旦认证管理器成功认证了Authentication请求,ProviderManager会立即调用concurrentSessionController验证当前用户的已登录信息。-->
<bean id="authenticationManager"
class="org.acegisecurity.providers.ProviderManager">
……
<!-- 增加 -->
<property name="sessionController" ref="concurrentSessionController"></property>
</bean>
学习Acegi应用到实际项目中(4)的更多相关文章
- 学习Acegi应用到实际项目中(10)- 保护业务方法
前面已经讲过关于保护Web资源的方式,其中包括直接在XML文件中配置和自定义实现FilterInvocationDefinitionSource接口两种方式.在实际企业应用中,保护Web资源非常重要, ...
- 学习Acegi应用到实际项目中(2)
Acegi应用到实际项目中(1)是基于BasicProcessingFilter的基本认证,这篇改用AuthenticationProcessingFilter基于表单的认证方式. 1.authent ...
- 学习Acegi应用到实际项目中(7)- 缓存用户信息
在默认情况下,即在用户未提供自身配置文件ehcache.xml或ehcache-failsafe.xml时,EhCache会依据其自身Jar存档包含的ehcache-failsafe.xml文件所定制 ...
- 学习Acegi应用到实际项目中(1)
在此,本人声明,我处于菜鸟阶段,文章的内容大部分摘自zhanjia的博客(http://zhanjia.iteye.com/category/43399),旨在学习,有很多地方,我理解不够透彻,可能存 ...
- 学习Acegi应用到实际项目中(12)- Run-As认证服务
有这样一些场合,系统用户必须以其他角色身份去操作某些资源.例如,用户A要访问资源B,而用户A拥有的角色为AUTH_USER,资源B访问的角色必须为AUTH_RUN_AS_DATE,那么此时就必须使用户 ...
- 学习Acegi应用到实际项目中(11)- 切换用户
在某些应用场合中,可能需要用到切换用户的功能,从而以另一用户的身份进行相关操作.这一点类似于在Linux系统中,用su命令切换到另一用户进行相关操作. 既然实际应用中有这种场合,那么我们就有必要对其进 ...
- 学习Acegi应用到实际项目中(9)- 实现FilterInvocationDefinition
在实际应用中,开发者有时需要将Web资源授权信息(角色与授权资源之间的定义)存放在RDBMS中,以便更好的管理.事实上,一般的企业应用都应当如此,因为这样可以使角色和Web资源的管理更灵活,更自由.那 ...
- 学习Acegi应用到实际项目中(8)- 扩展UserDetailsService接口
一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...
- 学习Acegi应用到实际项目中(5)
实际企业应用中,用户密码一般都会进行加密处理,这样才能使企业应用更加安全.既然密码的加密如此之重要,那么Acegi(Spring Security)作为成熟的安全框架,当然也我们提供了相应的处理方式. ...
随机推荐
- jmeter分布式、linux运行
一.jmeter分布式压测(多台电脑一起压测) 1.有多台电脑,每台电脑上都有jmeter,而且这几台电脑都互相能ping通 2.在我的电脑的jmeter,bin目录下,修改jmeter.proper ...
- 在pycharm_2018.2版本中开启Flask的debug的方法 (不要用命令:python **.py启动)
断点后,先ctl+c关闭控制台程序,再点击debuger调试 问题描述:在pycharm_2018.2版本中,我明确开启了debug,代码如下所示: from flask import Flask a ...
- IDEA查看类继承关系及生成类关系图
1.在想要查看的类上按 Ctrl + H -> Diagrams -> Show Diagrams -> Java Class Diagrams -> Show Impleme ...
- postgresql数据库3种程序(rule,trigger ,FUNCTION )
1. CREATE [ OR REPLACE ] RULE name AS ON event TO table_name [ WHERE condition ] DO [ ALSO | INSTEAD ...
- 权限管理demo-获取Spring上下文工具
package com.mmall.common; import org.springframework.beans.BeansException; import org.springframewor ...
- Android 开发 深入理解Handler、Looper、Messagequeue 转载
转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/73484527 本文已授权微信公众号 fanfan程序媛 独家发布 扫一扫文章底 ...
- 修改java在进程中的映像名
java小程序用java -jar xxx.jar 启动的进程映像名都是java.exe. 如果启动多个小程序就不好区分,导致监控程序无法定位到具体需要守护的小程序上. 解决办法: 在java安装目 ...
- MM-实际应用中的难题
SAP系统实际应用中的十大难题——塞依SAP培训 难题1:采购料维修 如果有物料坏了,需要退回给供应商处维修,此时一般不做退货.因为,第一,供应商不一定会乐意:第二,往来单据也无谓地增多:第三,最重要 ...
- JAVA程序调试
调试 步骤1:设置断点(不能在空白处设置断点) 步骤2:启动调试 步骤3:调试代码(F6单步跳过)笔记本Fn+F6(F5) 步骤4:结束调试 掌握调试的好处? l 很清晰的看到,代码执行的顺序 l ...
- VUE - 相对路径
background-image背景图片路径问题可以这样解决:1.先在data里面导入这张图片,例如: bg:require('./openIndexBG2.jpg')2 ...