<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
default-lazy-init="true">
<!-- ======================== FILTER过滤器 CHAIN链条 ======================= -->
<!-- http://blog.csdn.net/phevose/archive/2007/05/18/1615407.aspx
通过一系列的由spring托管的beans ,代理过滤请求。
FilterChainProxy 通过在web.xml中定义的FilterToBeanProxy 被加载,FilterChainProxy
将会通过init(FilterConfig), destroy() and doFilter(ServletRequest, ServletResponse, FilterChain)调用,
调用每一个在其中定义的过滤器。
FilterChainProxy:过滤器链条代理类
配置参数:
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转为小写,
PATTERN_TYPE_APACHE_ANT定义了使用Apache ant的匹配模式
/**=httpSessionContextIntegrationFilter......配置acegi使用的系列过滤器
httpSessionContextIntegrationFilter,
authenticationProcessingFilter,
securityContextHolderAwareRequestFilter,
rememberMeProcessingFilter,
anonymousProcessingFilter,
exceptionTranslationFilter,
filterInvocationInterceptor
-->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/images/**=#NONE#
/scripts/**=#NONE#
/styles/**=#NONE#
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
<!-- Put channelProcessingFilter before securityContextHolderAwareRequestFilter to turn on SSL switching -->
<!-- It's off by default b/c Canoo WebTest doesn't support SSL out-of-the-box -->
</property>
</bean>
<!--
每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象并组装ContextHolder。
ContextHolder主要用于存放SecureContext,包括用户的权限信息,在request完后,
又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
authentication:验证
-->
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
<!-- Changed to use logout.jsp since causes 404 on WebSphere: http://issues.appfuse.org/browse/APF-566 -->
<!--bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.jsp"/>
<constructor-arg>
<list>
<ref bean="rememberMeServices"/>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.jsp"/>
</bean-->
<!--
该Filter负责处理登陆身份验证。当接受到与filterProcessesUrl所定义相同的请求时,
它会首先通过 AuthenticationManager来验证用户身份。如果验证成功,则重定向到defaultTargetUrl所定义的成功登陆页面。
如果验证失败,则再从rememberMeServices中获取用户身份,若再获取失败,则重定向到authenticationFailureUrl所定义登陆失败页面。
-->
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/login.jsp?error=true"/><!-- 登录失败的url -->
<property name="defaultTargetUrl" value="/"/><!-- 登录成功后的url -->
<property name="filterProcessesUrl" value="/j_security_check"/><!-- 需要这个filter处理的url -->
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<!--
该Filter负责通过Decorate Model(装饰模式),装饰的HttpServletRequest对象。
其Wapper是ServletRequest包装类 HttpServletRequestWrapper的子类
(SavedRequestAwareWrapper或 SecurityContextHolderAwareRequestWrapper),
附上获取用户权限信息,request参数,headers, Date headers 和 cookies 的方法。
在appfuse中使用的struts-menu.xml对用户菜单权限的控制参数role进行配置时必须结合该Filter,
因为该filter有isUserInRole方法,而struts menu也是通过request.isUserInRole方法来控制菜单是否显示的
-->
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
<!-- 该Filter负责在用户登录后在本地机上记录用户cookies信息,免除下次再次登陆。
检查AuthenticationManager 中是否已存在Authentication对象,如果不存在则会调用RememberMeServices
的aotoLogin方法来从cookies中获取Authentication对象
-->
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<!-- 该Filter负责为当不存在任何授权信息时,自动为Authentication对象添加userAttribute中定义的匿名用户权限 -->
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="anonymous"/>
<property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/>
</bean>
<!-- 该过滤器负责处理各种异常,然后重定向到相应的页面中。
-->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"/>
</property>
</bean>
<!-- 该过滤器会首先调用AuthenticationManager判断用户是否已登陆认证,如还没认证成功,则重定向到登陆界面。
认证成功,则并从 Authentication中获取用户的权限。然后从objectDefinitionSource属性获取各种URL资源所对应的权限。
最后调用 AccessDecisionManager来判断用户所拥有的权限与当前受保华的URL资源所对应的权限是否相匹配。如果匹配失败,
则返回403错误 (禁止访问)给用户。匹配成功则用户可以访问受保护的URL资源。
-->
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/admin/*=ROLE_ADMIN
/passwordHint.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER
/signup.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER
/a4j.res/*.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER <!-- APF-737, OK to remove if not using JSF -->
/**/*.html*=ROLE_ADMIN,ROLE_USER
</value>
</property>
</bean>
<bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter"/>
<!-- 这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀?这里没加
-->
</list>
</property>
</bean>
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDao"/>
<property name="key" value="23_*!cdU='612./e;NrI"/>
<property name="parameter" value="rememberMe"/>
</bean>
<!-- authenticationManager http://intozgc.zhuaxia.com/pre_channel/4951525
起到认证管理的作用,它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
Acegi提供了不同的AuthenticationProvider的实现,如:
DaoAuthenticationProvider 从数据库中读取用户信息验证身份
AnonymousAuthenticationProvider 匿名用户身份认证
RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
AuthByAdapterProvider 使用容器的适配器验证身份
CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登陆
JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证身份
RemoteAuthenticationProvider 根据远程服务验证用户身份
RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
X509AuthenticationProvider 从X509认证中获取用户信息验证身份
TestingAuthenticationProvider 单元测试时使用
每个认证者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。
-->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="anonymous"/>
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="23_*!cdU='612./e;NrI"/>
</bean>
<!-- The following beans are defined in applicationContext-service.xml, which is stored in appfuse-service.jar -->
<!--
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDao"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
</bean>
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.ShaPasswordEncoder"/>
-->
<!-- Uncomment to disabling password encryption -->
<!-- <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.PlaintextPasswordEncoder"/> -->
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
<!-- Apply method-level interceptor to userManager bean -->
<aop:config>
<aop:advisor id="managerSecurity" advice-ref="methodSecurityInterceptor" pointcut="execution(* org.appfuse.service.UserManager.*(..))"/>
</aop:config>
<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
org.appfuse.service.UserManager.getUsers=ROLE_ADMIN
org.appfuse.service.UserManager.removeUser=ROLE_ADMIN
</value>
</property>
</bean>
<!-- SSL Switching: to use this, configure it in the filterChainProxy bean -->
<bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager" ref="channelDecisionManager"/>
<property name="filterInvocationDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/admin/**=REQUIRES_SECURE_CHANNEL
/login*=REQUIRES_SECURE_CHANNEL
/j_security_check*=REQUIRES_SECURE_CHANNEL
/editProfile.html*=REQUIRES_SECURE_CHANNEL
/signup.html*=REQUIRES_SECURE_CHANNEL
/saveUser.html*=REQUIRES_SECURE_CHANNEL
/**=REQUIRES_INSECURE_CHANNEL
</value>
</property>
</bean>
<bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<bean class="org.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean class="org.acegisecurity.securechannel.InsecureChannelProcessor"/>
</list>
</property>
</bean>
</beans>