技术开发 频道

使用Acegi进行身份认证(之一)

使用代理过滤器链对处理HTTP请求

Acegi通过众多的过滤器完成不同安全控制的任务,在前面我们提到了三个过滤器:HttpSessionContextIntegrationFilter、ExceptionTranslationFilter和ChannelProcessingFilter。除此以外,还有LogoutFilter、AuthenticationProcessingFilter等不下10个的过滤器。

当需要配置多个Servlet过滤器时,虽然我们可以通过FilterToBeanProxy分别进行配置,但这将导致冗长难看的web.xml,同时还需要小心谨慎地通过过滤器的配置顺序保证它们的调用顺序。为了解决这个问题,Acegi在0.8版本中添加了一个org.acegisecurity.util.FilterChainProxy。FilterChainProxy可以同时指定多个过滤器并将它们组成一个过滤器链,而FilterToBeanProxy只要将代理目标设置为FilterChainProxy就可以了。来看下面的配置:

代码清单 1 web.xml
<web-app> <context-param> ①指定Spring配置文件 <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext.xml, classpath:applicationContext-acegi-plugin.xml </param-value> </context-param> <filter>②将过滤器委托给FilterChainProxy <filter-name>AcegiFilterChainProxy</filter-name> <filter-class> org.acegisecurity.util.FilterToBeanProxy </filter-class> <init-param> <param-name>targetClass</param-name> <param-value> org.acegisecurity.util.FilterChainProxy </param-value> </init-param> </filter> <filter-mapping>③对所有的URL进行过滤 <filter-name>AcegiFilterChainProxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> … </web-app>
在web.xml中我们首先需要定义Spring的配置文件,以便将Spring容器集成到Servlet容器中。紧接着,我们定义一个FilterToBeanProxy的过滤器拦截所有URL请求并委托给FilterChainProxy进行处理。FilterChainProxy在Spring容器中定义如下所示:

代码清单 2 applicationContext-acegi-plugin.xml
<beans> <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">①目标委托的Bean <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_UPPERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT ②多个过滤器组成的过滤器链 /**=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter </value> </property> </bean> <bean id="channelProcessingFilter" ③过滤器链中的过滤器(1) class="org.acegisecurity.securechannel.ChannelProcessingFilter"> … </bean> <bean id="httpSessionContextIntegrationFilter" ④过滤器链中的过滤器(2) class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"> … </bean> … </beans>
在①处定义的FilterChainProxy Bean是web.xml的FilterToBeanProxy的委托目标。FilterChainProxy通过filterInvocationDefinitionSource定义多个相互链接的过滤器,如②所示。这些过滤器以逗号分隔,它表示web.xml中定义的匹配URL(/*)请求将分别通过channelProcessingFilter、httpSessionContextIntegrationFilter及logoutFilter这三个过滤器的拦截处理。这个过滤器链通过过滤器对应的Bean名字(如③和④)进行定义,过滤器都实现了javax.servlet .Filter接口。你完全可以参照实例方式定义多组滤器链,以便处理不同URL请求。不过,在一般情况下,你只要配置一个过滤器链就可以了。

filterInvocationDefinitionSource属性由两类信息组成:其一是指令信息,如

CONVERT_URL_TO_UPPERCASE_BEFORE_COMPARISON表示判断URL匹配时,首先将URL转变为大写的格式,如果设置为CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON则表示比较前事先转换为小写的形式。而PATTERN_TYPE_APACHE_ANT表示使用Ant路径风格进行匹配URL的描述,如果不提供这个指令,Acegi使用正则表达式来解析URL路径映射。
0
相关文章