- 浏览: 3500717 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
Acegi 中的 HttpSessionEvent 监听机制 窥视 Acegi 的 工作流程。
Acegi 结合了 Spring 提供了不错的 HttpSessionEvent 监听机制
使用 Acegi 的 HttpSessionEvent 监听机制,我首先要在 web.xml 中增加一个 Listener
org.acegisecurity.ui.session.HttpSessionEventPublisher
有人要问这不是一个 Listener 么,类名应该是一个 *Listener 什么的啊。的确它实现了 javax.servlet.ServletContextListener 接口和 javax.servlet.http.HttpSessionListener 接口。前者是在 web 应用创建时,可以可以通过 ServletContext 来获取一个 Spring 的 ApplicationContext 。后者是在 HttpSession 创建和超时时发布利用 Spring 的 ApplicationContext. publishEvent() 方法发布事件的,注意并不时发布的 HttpSesionEvent ,而是有 HttpSession 作为构造参数,创建了 HttpSessionCreatedEvent 、 HttpSessionDestroyedEvent ,这两个 Event 都是 Spring 的 ApplicationEvent 的子类,这样 Spring 才会处理这些 Event 。事件发布后, Spring 会在上下文查找实现了 ApplicationListener 接口的接口子类来处理这两个 Event 的
到这,你心里或许有些疑惑, HttpSessionEvent 发布了,那个 ApplicationListener 来处理这个 HttpSessionEvent 呢?注意,重要人物出场了。
org.acegisecurity.concurrent. SessionRegistryImpl 出场了。看了它的源代码,你会发现它还实现另外一个接口 org.acegisecurity.concurrent. SessionRegistry ,
这个定义如下一些方法
public interface SessionRegistry { public Object[] getAllPrincipals(); public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions); public SessionInformation getSessionInformation(String sessionId); public void refreshLastRequest(String sessionId); public void registerNewSession(String sessionId, Object principal) throws SessionAlreadyUsedException; public void removeSessionInformation(String sessionId); } |
这些方法的功能通过看方法名就能知道了。
看一下 SessionRegistryImpl. onApplicationEvent() 方法,看它做了些什么
public void onApplicationEvent(ApplicationEvent event) { if (event instanceof HttpSessionDestroyedEvent) { String sessionId = ((HttpSession) event.getSource()).getId(); removeSessionInformation(sessionId); } } |
它怎么只处理 HttpSessionDestoryedEvent ,这就说 SessionRegistryImpl 只处理 HttpSession 的销毁,也就是这又是为什么呢。如果你仔细看了 SessionRegistry 的接口定义,或许能明白一些, SessionRegistryImpl 需要存储客户端用户的 SessionInformation , SessionInformation 里面又有什么, SesssionInformation 有四个字段
private Date lastRequest; private Object principal; private String sessionId; private boolean expired = false; |
除了 principal ,其他三个字段应该很容易理解,那这个 Principal 是什么东西呢, Principal 可以理解为当前客户端用户的身份信息,这个身份信息可以包含用户名,用户密码,用户在系统里面拥有的权限。 Acegi 提供了一个 UserDetail 来表示用户的身份。
public interface UserDetails extends Serializable { public GrantedAuthority[] getAuthorities(); public String getPassword(); public String getUsername(); public boolean isAccountNonExpired(); public boolean isAccountNonLocked(); public boolean isCredentialsNonExpired(); public boolean isEnabled(); } |
顺便提一下 SessionRegistryImpl 处理 HttpSessionDestoryedEvent 是,只是把这个 HttpSesion 的有关信息也就是 SessionInformation 从存储中移出。
通过上面的分析,你觉得每当新的 HttpSession 创建时, SessionRegistryImpl 也处理这个 Event 还有意义吗?事实上 SessionRegistryImpl 没有处理 HttpSessionCreatedEvent , Acegi 也没有提供其他的 Spring ApplicationListener 来处理这个 HttpSessionCreatedEvent 。
注意,我们的程序一般并不用直接与 SessionRegistryImpl 打交道,你只需在 Spring 的配置文件定义一个 Bean 就行了,如
< bean id = "sessionRegistry" class = "org.acegisecurity.concurrent.SessionRegistryImpl" /> |
只是如此而已。
那么当 HttpSession 创建时, Acegi 并不做处理,还会有其他的咚咚来处理么; SessionRegistryImpl 还需要存储用户的 Principal ,那么什么咚咚与 SessionRegistryImpl 打交道呢?
有,但不过不是 ApplicationListener 了,别忘了, SpringSide 还定义了一系列的 Filter 让 Acegi 来做过滤(详情请见 org.springside.bookstore.plugins.security. applicationContext-security-acegi.xml ),那什么 Filter 与实现了 SessionRegistry 接口的 SessionRegistryImpl 打交道呢?下面我来介绍一下 ConcurrentSessionFilter ,这个 Filter 是与 SessionRegistryImpl 打交道的。我们先看一下该 Filter 的 doFilter() 的方法 ( 截取了部分代码 ) 。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ------------------
HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession session = httpRequest.getSession(false);
if (session != null) { SessionInformation info = sessionRegistry.getSessionInformation(session.getId());
if (info != null) { if (info.isExpired()) { // Expired - abort processing session.invalidate();
String targetUrl = httpRequest.getContextPath() + expiredUrl; //Session 已经过期,转向一个 targetUrl ,比如登陆页面 httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
return; } else { // Non-expired - update last request date/time info.refreshLastRequest(); } } }
chain.doFilter(request, response); } |
各位看官可能要问为什么要调用 SessionInformation.isExpired() 来检测通过 HttpSession 的 id 来获取 SessionInformation 是否过期呢,过期 ( 超时 ) 的 SessionInformation 不是由 SessionRegistryImpl 清除掉了吗?
如果你能跟我一样发现这个问题,说明看得比较仔细和投入 :)
下面来介绍一下 ConcurrentSessionController 接口,因为 SpringSide 里面用了这个实现,所以一定要介绍下:)。
ConcurrentSessionController 接口有两个方法: public void checkAuthenticationAllowed(Authentication request) 和 public void registerSuccessfulAuthentication(Authentication authentication) 。前一个方法检查当前用户请求的认证 ( 这里是姑且把 Authentication 翻译成认证 ) 是否是系统允许的,如果没有经过允许则抛出 AuthenticationException 异常给 Acegi 处理;后一个方法把认证赋予当前用户。
Acegi 提供 ConcurrentSessionController 接口的一个增强实现 ConcurrentSessionControllerImpl ,提供更多的控制策略,比如配置是否允许用户重复登陆,最多允许多少个 HttpSession 。
下面看下 ConcurrentSessionController 的接口实现 ConcurrentSessionControllerImpl ,不过是我们只看其中一部分, Aecgi 是怎么让 SessionInformation 过期的
// 允许 HttpSession 超过设定值 protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions, SessionRegistry registry) { if (exceptionIfMaximumExceeded || (sessions == null)) { throw new ConcurrentLoginException(messages.getMessage("ConcurrentSessionControllerImpl.exceededAllowed", new Object[] {new Integer(allowableSessions)}, "Maximum sessions of {0} for this principal exceeded")); } // 检查 SessionRegistryImpl 中最后更新的 SessionInformation SessionInformation leastRecentlyUsed = null;
for (int i = 0; i < sessions.length; i++) { if ((leastRecentlyUsed == null) || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) { leastRecentlyUsed = sessions[i]; } } // 找到一个倒霉蛋,对不起,我要把你的 SessionInformation 设置为过期,这样 ConcurrentSessionFilter 在处理到你的 SessionInformation 时会让你重新登陆系统 leastRecentlyUsed.expireNow(); }
|
分析到这里,不禁感叹一句, Acegi 提供了多么贴心的功能,感激得快流泪了。
写了这么多,你也看了这么多,快要骂我了,写了这么多,就说了 Acegi 怎么处理 HttpSession 超时,怎么处理每个 HttpSession 中的用户信息,怎么管理 Session 用户,以及那个倒霉蛋,还有那个倒霉蛋转到登陆页面再次输入用户名和密码的。
那用户访问受限资源时, Acegi 又是怎么做的呢。好,各位稍休息一会,我也抽根烟调整下思路。
好,第二部分开始了。 Acegi 怎么保护受限资源的。这里稍微点一下,资源可以分为多种,比如某个类的方法啊, URL 啊,只要写相应的拦截器去处理就 OK 了。拦截器检查到该用户没有权限访问资源,很简单,抛出异常 ( 至于针对方法和 URL 的拦截器是怎么工作的,这部分我们先不讲 )
好戏正式开始 ---Acegi 怎么处理这个异常的。你可以已经想到了,使用 Filter 。对,是 Filter ! Acegi 定义个 Filter ,用来处理这些异常,这个 Filter 是 org.acegisecurity.ui.ExceptionTranslationFilter , ExceptionTranslationFilter
try { chain.doFilter(request, response); if (logger.isDebugEnabled()) { logger.debug("Chain processed normally");
|
发表评论
-
说明SOA监管(SOA Governance)实例(收录备查)
2012-12-19 11:35 1750SOA 已经不是单纯技术问 ... -
Injecting Spring Beans into Java Servlets
2012-11-01 10:21 1934If you are working in a Java ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3757原文出处:http://blog.chenlb.com/200 ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:17 3881When I try to install the And ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:13 1986When I try to install the And ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14838大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1709charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22612Java Native Access 项目 在 ... -
使用IntrospectorCleanupListener 解决quartz引起的内存泄漏
2011-04-20 11:59 13362"在服务器运行过程中,Spring不停的运行的计划任 ... -
DBCP代码研读以及就数据库连接失效的解决
2011-03-31 11:03 3762问题 网上很多评论说DBCP有很多BUG,但是都没有指明是什 ... -
ContextLoaderListener
2010-12-06 15:58 8459(1) org.springframework.web.c ... -
Servlet3.0新功能: 异步处理
2010-12-06 15:22 3177J2EE 6和Glassfish 3V正式发 ... -
Servlet3.0引入的新特性
2010-12-06 15:20 3054Servlet3.0规范的新特性主要是为了3个目的: ... -
100個節點上運行群集亞馬遜EC2上Hazelcast
2010-12-03 23:59 3315本文的目的,適是给妳湮示的細節集群的100個節點。此湮示記錄, ... -
Spring Properties Reloaded
2010-12-02 14:54 4369Spring Properties Reloaded Som ... -
为spring2.5中的jpetstore增加perf4j监控
2010-09-02 13:51 2640perf4j是一款类似于log4j的性能检测工具. 它 ... -
语义网的学习资源大汇集(备忘)
2010-06-23 22:48 1732网上资源 http:/ ... -
使用 JOLAP 实现复杂分析查询
2010-06-06 13:42 1962Shashank Tiwari 在本文中对 ... -
HTML5 Canvas for Internet Explorer
2010-06-04 21:16 1856Canvascape http://www.benjoff ... -
大型网站架构演变和知识体系
2010-06-01 23:47 1959架构演变第一步:物 ...
相关推荐
4. **过滤器安全链(Filter Security Interceptor)**:Acegi的核心组件之一,它是一个Spring MVC的过滤器,会在请求被处理之前检查用户的权限。如果用户没有足够的权限,过滤器将阻止请求的进一步处理。 5. **频道...
Acegi 是一个在Java开发领域,特别是Spring框架中曾经广泛使用的安全组件,全称为Acegi Security。这个系统为Spring应用程序提供了全面的安全管理解决方案,包括身份验证、授权、会话管理以及安全事件处理等功能。...
在 `web.xml` 中,你需要定义一个名为 `Acegi Filter Chain Proxy` 的过滤器,并将其映射到所有 URL,以便拦截并处理每个请求。过滤器类使用 `FilterToBeanProxy` 创建 `FilterChainProxy` 的实例,`...
Acegi是一个专门为SpringFramework应用提供安全机制的开放源代码项目,全称为Acegi Security System for Spring,当前版本为 0.8.3。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和...
Spring Acegi是一个安全框架,它为Spring应用提供了一套强大的身份验证和授权机制。这个框架在Spring Security(之前称为Spring Security)之前被广泛使用。在本文中,我们将深入探讨Spring Acegi的核心概念、功能和...
总的来说,Acegi Security(Spring Security)是Spring生态中的重要组成部分,它提供了一种高效且灵活的方式来管理和保护应用程序的安全,确保用户访问控制的准确性和严密性,从而保障系统的稳定运行。通过深入理解...
3. **过滤器安全链(Filter Security Interceptor)**:Acegi的核心组件之一,它是Servlet过滤器,负责拦截请求并根据配置的策略进行身份验证和授权。 4. **安全性配置(Security Configurations)**:在Spring应用...
AceGI,全称为Acegi Security,是Java领域中一个用于Spring框架的安全组件,它提供了全面的身份验证、授权和会话管理功能。这个框架在早期的Spring版本中非常流行,为开发者构建安全的Web应用程序提供了强大的支持。...
这个"spring acegi 使用工程demo"显然是一个示例项目,旨在帮助开发者理解和实践如何在Spring应用中集成和使用Acegi安全框架。 首先,Acegi是Spring Security的前身,后来被Spring Security所取代,但它的概念和...
在Web应用中, AceGI提供了一套强大的访问控制和身份验证机制,而CAS则作为外部认证服务器,可以为多个应用提供统一的用户验证。通过整合两者,可以简化用户登录流程,同时加强整体系统的安全性。 1.2 环境: 整合...
Acegi安全框架通过一系列关键组件来实现这些功能,同时它还具备高度的灵活性,可以与各种认证机制(如容器认证、CASSSO、X509等)进行整合,以适应不同的应用场景。 #### Acegi的关键组件 Acegi安全系统由多个关键...
Acegi Security,现已被Spring Security所取代,是Java EE应用程序中的一个强大且灵活的权限管理框架。它提供了全面的身份验证、授权和访问控制功能,旨在确保企业级应用的安全性。Acegi通过AOP(面向切面编程)的...
Acegi Security是Spring框架早期的一个安全模块,它提供了全面的基于Spring的应用程序的安全管理功能。在本实例中,我们将深入探讨如何使用Acegi来控制用户的权限。Acegi Security已经被Spring Security替代,但其...
Acegi Security是一款在Java平台上广泛使用的安全框架,它为Spring应用程序提供了高级的身份验证、授权和服务保护功能。在本文中,我们将深入探讨Acegi Security 1.0.7版本中的核心概念和关键特性。 首先,我们要...
Acegi是Spring Security的前身,它是一个用于Java平台的安全框架,专为Spring应用程序设计。本教程将引导初学者逐步了解如何在实际项目中应用Acegi安全框架,以便为你的Web应用提供强大的身份验证和授权功能。 首先...
Acegi Security是一个专门为Spring框架设计的权限控制框架,旨在为基于J2EE的企业级应用程序提供全面的安全服务。这个框架解决了J2EE规范中安全性配置不便于移植的问题,使得应用程序的安全设置能够在不同服务器环境...
Acegi Security是一个已退役的安全框架,它为Java平台上的Spring框架提供了全面的身份验证和授权服务。这个"acegi-security-tiger-1.0.0-RC2.jar.zip"压缩包包含的是Acegi Security的一个早期版本——1.0.0 Release ...
Acegi-Spring安全框架是一个专为基于Spring的企业应用设计的安全框架,现在被称为Spring Security。它提供了声明式的安全访问控制,允许开发者在Spring容器中配置安全相关的Bean,利用Spring的依赖注入(IoC)和面向...
本实战教程将深入探讨如何将Acegi Security集成到Spring框架中,构建一个安全的WEB应用程序。 首先,我们需要理解Acegi Security的核心概念。Acegi Security基于Spring AOP(面向切面编程)原理,允许开发者通过...
Acegi安全系统,是一个用于Spring Framework的安全框架,能够和目前流行的Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和面向接口的编程方式。因此,Acegi安全...