<?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:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<!--
FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring Ioc的功能,
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 定义url比较前先转为小写
PATTERN_TYPE_APACHE_ANT 定义使用Apache ant的匹配模式
-->
<bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
]]></value>
</property>
</bean>
<!--
集成过滤器( HttpSessionContextIntegrationFilter 是集成过滤器的一个实现)
每次 request 前 HttpSessionContextIntegrationFilter 从 Session 中获取 Authentication 对象,在 request 完后
又把 Authentication 对象保存到 Session 中供下次 request 使用,此 filter 必须在其他 Acegi filter前使用
-->
<bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
<!--
退出(Logout)过滤器 退出登录操作
-->
<bean id="logoutFilter"
class="org.springframework.security.ui.logout.LogoutFilter">
<!-- 退出系统后系统跳转到此URL -->
<constructor-arg value="/login.action"/>
<!-- 退出系统后的操作(调用logout方法) -->
<constructor-arg>
<list>
<!-- 实现了LogoutHandler接口(logout方法) -->
<ref bean="rememberMeServices"/>
<bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<!--
处理表单认证filter:
1.authenticationManager 认证管理器
2.authenticationFailureUrl 定义登录失败时转向的页面
3.defaultTargetUrl 定义登录成功时转向的页面
4.filterProcessesUrl 定义登录请求的地址
5.rememberMeServices 在验证成功后添加cookie信息
-->
<bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"
p:authenticationManager-ref="authenticationManager"
p:authenticationFailureUrl="/login.action?login_error=1"
p:defaultTargetUrl="/user.action"
p:filterProcessesUrl="/j_spring_security_check"
p:rememberMeServices-ref="rememberMeServices"/>
<!--
认证管理器( org.springframework.security.AuthenticationManager 接口)
org.springframework.security.providers.ProviderManager是认证管理器的一个实现,
ProviderManager通过遍历一个提供者的集合来实现身份验证,
直到某一个认证提供者能够成功地验证该用户的身份
-->
<!--
通过Providers提供认证者列表,如果一个认证提供者失败可以尝试另外一个认证提供者,以保证获取不同来源的身份认证,如
DaoAuthenticationProvider 从数据库中读取用户信息验证身份
AnonymousAuthenticationProvider 匿名用户身份认证
RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
其它的还有
AuthByAdapterProvider 使用容器的适配器验证身份
CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登陆
JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证身份
RemoteAuthenticationProvider 根据远程服务验证用户身份
RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
X509AuthenticationProvider 从X509认证中获取用户信息验证身份
TestingAuthenticationProvider 单元测试时使用
每个认证者会对自己指定的证明信息进行认证,如 DaoAuthenticationProvider 仅对 UsernamePasswordAuthenticationToken 这个证明信息进行认证。
-->
<bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager"
p:sessionController-ref="concurrentSessionController">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<bean
class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider"
p:key="springsecurity"/>
<bean
class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"
p:key="springsecurity"/>
</list>
</property>
</bean>
<!-- 阻止用户在成功登录之后再进行一次成功登录 -->
<bean id="concurrentSessionController"
class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl"
p:maximumSessions="1"
p:exceptionIfMaximumExceeded="true"
p:sessionRegistry-ref="sessionRegistry"
p:messageSource-ref="messageSource"/>
<bean id="sessionRegistry"
class="org.springframework.security.concurrent.SessionRegistryImpl"/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="/WEB-INF/classes/messages_zh_CN"/>
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>
<!--
利用cookie自动登陆filter
当 SecurityContextHolder 中不存在 Authentication 用户授权信息,
rememberMeProcessingFilter 就会调用 autoLogin() 方法从cookie中获取用户信息,在验证 filter 之前使用
-->
<bean id="rememberMeProcessingFilter"
class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter"
p:authenticationManager-ref="authenticationManager"
p:rememberMeServices-ref="rememberMeServices"/>
<!--
如果不存在任何授权信息时,自动添加匿名用户身份至 SecurityContextHolder 中
-->
<bean id="anonymousProcessingFilter"
class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter"
p:key="springsecurity"
p:userAttribute="anonymousUser,ROLE_ANONYMOUS"/>
<!--
异常处理filter(异常转换过滤器),主要是处理 AccessDeniedException 和 AuthenticationException,
将给每个异常找到合适的"去向"
-->
<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter"
p:accessDeniedHandler-ref="accessDeniedHandler"
p:authenticationEntryPoint-ref="authenticationEntryPoint"/>
<!-- 处理 AccessDeniedException -->
<bean id="accessDeniedHandler"
class="org.springframework.security.ui.AccessDeniedHandlerImpl"
p:errorPage="/accessDenied.jsp"/>
<!-- 处理 AuthenticationException -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint"
p:loginFormUrl="/login.action"
p:forceHttps="false"/>
<!--
使用过滤器安全拦截器保护资源
filterSecurityInterceptor 在执行转向目标 url 前检查 objectDefinitionSource 中设定的用户权限信息,
安全强制过滤器负责拦截请求,判断请求是否安全,并且给予认证和访问决策管理器一个机会来验证用户的身份和权限
过程:
首先,过滤器安全拦截器使用 authenticationManager 调用自己的 provider 来对用户的认证信息进行验证并获取用户已有的权限。
然后,使用访问决策管理器来判断用户是否拥用合适的授权来访问受保护的资源。
(objectDefinitionSource 属性定义了访问 URL 需要的权限信息)
最后,有投票者根据用户持有认证和访问 url 需要的属性,调用自己的 voter 来投票,决定是否允许访问。
-->
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor"
p:authenticationManager-ref="authenticationManager"
p:accessDecisionManager-ref="accessDecisionManager"
p:objectDefinitionSource-ref="objectDefinitionSource">
</bean>
<bean id="objectDefinitionSource"
class="com.shopin.modules.security.intercept.web.DataBaseFilterInvocationDefinitionSource"
p:convertUrlToLowercaseBeforeComprison="true"
p:useAntPath="true"
p:cacheManager-ref="securityCacheManager"/>
<!--
访问决策管理器
验证用户是否有权限访问相应的资源(filterSecurityInterceptor 中 objectDefinitionSource 属性定义的访问URL需要的属性信息)
-->
<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased"
p:allowIfAllAbstainDecisions="false">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter"/>
<bean class="org.springframework.security.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="rememberMeServices"
class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices"
p:key="springsecurity"
p:userDetailsService-ref="userDetailsService"/>
<bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider"
p:userCache-ref="userCache"
p:passwordEncoder-ref="passwordEncoder"
p:userDetailsService-ref="userDetailsService"/>
<bean id="passwordEncoder"
class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
<!-- 缓存配置 -->
<bean id="resourceCache"
class="com.shopin.modules.security.resourcedetails.EhCacheResourceCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:cacheName="resourceCache"/>
</property>
</bean>
<bean id="userCache"
class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:cacheName="userCache"/>
</property>
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache-hibernate.xml">
</bean>
<bean id="userDetailsService" class="cn.shopin.miniweb.service.security.UserDetailServiceImpl"/>
<bean id="securityCacheManager"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
p:transactionManager-ref="transactionManager"
p:proxyTargetClass="true">
<property name="target">
<bean class="com.shopin.modules.security.cache.SecurityCacheManagerImpl"
p:sessionFactory-ref="sessionFactory"
p:resourcCache-ref="resourceCache"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="init*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener"/>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<!--
FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring Ioc的功能,
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 定义url比较前先转为小写
PATTERN_TYPE_APACHE_ANT 定义使用Apache ant的匹配模式
-->
<bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
]]></value>
</property>
</bean>
<!--
集成过滤器( HttpSessionContextIntegrationFilter 是集成过滤器的一个实现)
每次 request 前 HttpSessionContextIntegrationFilter 从 Session 中获取 Authentication 对象,在 request 完后
又把 Authentication 对象保存到 Session 中供下次 request 使用,此 filter 必须在其他 Acegi filter前使用
-->
<bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
<!--
退出(Logout)过滤器 退出登录操作
-->
<bean id="logoutFilter"
class="org.springframework.security.ui.logout.LogoutFilter">
<!-- 退出系统后系统跳转到此URL -->
<constructor-arg value="/login.action"/>
<!-- 退出系统后的操作(调用logout方法) -->
<constructor-arg>
<list>
<!-- 实现了LogoutHandler接口(logout方法) -->
<ref bean="rememberMeServices"/>
<bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
<!--
处理表单认证filter:
1.authenticationManager 认证管理器
2.authenticationFailureUrl 定义登录失败时转向的页面
3.defaultTargetUrl 定义登录成功时转向的页面
4.filterProcessesUrl 定义登录请求的地址
5.rememberMeServices 在验证成功后添加cookie信息
-->
<bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"
p:authenticationManager-ref="authenticationManager"
p:authenticationFailureUrl="/login.action?login_error=1"
p:defaultTargetUrl="/user.action"
p:filterProcessesUrl="/j_spring_security_check"
p:rememberMeServices-ref="rememberMeServices"/>
<!--
认证管理器( org.springframework.security.AuthenticationManager 接口)
org.springframework.security.providers.ProviderManager是认证管理器的一个实现,
ProviderManager通过遍历一个提供者的集合来实现身份验证,
直到某一个认证提供者能够成功地验证该用户的身份
-->
<!--
通过Providers提供认证者列表,如果一个认证提供者失败可以尝试另外一个认证提供者,以保证获取不同来源的身份认证,如
DaoAuthenticationProvider 从数据库中读取用户信息验证身份
AnonymousAuthenticationProvider 匿名用户身份认证
RememberMeAuthenticationProvider 已存cookie中的用户信息身份认证
其它的还有
AuthByAdapterProvider 使用容器的适配器验证身份
CasAuthenticationProvider 根据Yale中心认证服务验证身份, 用于实现单点登陆
JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证身份
RemoteAuthenticationProvider 根据远程服务验证用户身份
RunAsImplAuthenticationProvider 对身份已被管理器替换的用户进行验证
X509AuthenticationProvider 从X509认证中获取用户信息验证身份
TestingAuthenticationProvider 单元测试时使用
每个认证者会对自己指定的证明信息进行认证,如 DaoAuthenticationProvider 仅对 UsernamePasswordAuthenticationToken 这个证明信息进行认证。
-->
<bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager"
p:sessionController-ref="concurrentSessionController">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
<bean
class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider"
p:key="springsecurity"/>
<bean
class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"
p:key="springsecurity"/>
</list>
</property>
</bean>
<!-- 阻止用户在成功登录之后再进行一次成功登录 -->
<bean id="concurrentSessionController"
class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl"
p:maximumSessions="1"
p:exceptionIfMaximumExceeded="true"
p:sessionRegistry-ref="sessionRegistry"
p:messageSource-ref="messageSource"/>
<bean id="sessionRegistry"
class="org.springframework.security.concurrent.SessionRegistryImpl"/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="/WEB-INF/classes/messages_zh_CN"/>
<bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>
<!--
利用cookie自动登陆filter
当 SecurityContextHolder 中不存在 Authentication 用户授权信息,
rememberMeProcessingFilter 就会调用 autoLogin() 方法从cookie中获取用户信息,在验证 filter 之前使用
-->
<bean id="rememberMeProcessingFilter"
class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter"
p:authenticationManager-ref="authenticationManager"
p:rememberMeServices-ref="rememberMeServices"/>
<!--
如果不存在任何授权信息时,自动添加匿名用户身份至 SecurityContextHolder 中
-->
<bean id="anonymousProcessingFilter"
class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter"
p:key="springsecurity"
p:userAttribute="anonymousUser,ROLE_ANONYMOUS"/>
<!--
异常处理filter(异常转换过滤器),主要是处理 AccessDeniedException 和 AuthenticationException,
将给每个异常找到合适的"去向"
-->
<bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter"
p:accessDeniedHandler-ref="accessDeniedHandler"
p:authenticationEntryPoint-ref="authenticationEntryPoint"/>
<!-- 处理 AccessDeniedException -->
<bean id="accessDeniedHandler"
class="org.springframework.security.ui.AccessDeniedHandlerImpl"
p:errorPage="/accessDenied.jsp"/>
<!-- 处理 AuthenticationException -->
<bean id="authenticationEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint"
p:loginFormUrl="/login.action"
p:forceHttps="false"/>
<!--
使用过滤器安全拦截器保护资源
filterSecurityInterceptor 在执行转向目标 url 前检查 objectDefinitionSource 中设定的用户权限信息,
安全强制过滤器负责拦截请求,判断请求是否安全,并且给予认证和访问决策管理器一个机会来验证用户的身份和权限
过程:
首先,过滤器安全拦截器使用 authenticationManager 调用自己的 provider 来对用户的认证信息进行验证并获取用户已有的权限。
然后,使用访问决策管理器来判断用户是否拥用合适的授权来访问受保护的资源。
(objectDefinitionSource 属性定义了访问 URL 需要的权限信息)
最后,有投票者根据用户持有认证和访问 url 需要的属性,调用自己的 voter 来投票,决定是否允许访问。
-->
<bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor"
p:authenticationManager-ref="authenticationManager"
p:accessDecisionManager-ref="accessDecisionManager"
p:objectDefinitionSource-ref="objectDefinitionSource">
</bean>
<bean id="objectDefinitionSource"
class="com.shopin.modules.security.intercept.web.DataBaseFilterInvocationDefinitionSource"
p:convertUrlToLowercaseBeforeComprison="true"
p:useAntPath="true"
p:cacheManager-ref="securityCacheManager"/>
<!--
访问决策管理器
验证用户是否有权限访问相应的资源(filterSecurityInterceptor 中 objectDefinitionSource 属性定义的访问URL需要的属性信息)
-->
<bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased"
p:allowIfAllAbstainDecisions="false">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.vote.RoleVoter"/>
<bean class="org.springframework.security.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
<bean id="rememberMeServices"
class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices"
p:key="springsecurity"
p:userDetailsService-ref="userDetailsService"/>
<bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider"
p:userCache-ref="userCache"
p:passwordEncoder-ref="passwordEncoder"
p:userDetailsService-ref="userDetailsService"/>
<bean id="passwordEncoder"
class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
<!-- 缓存配置 -->
<bean id="resourceCache"
class="com.shopin.modules.security.resourcedetails.EhCacheResourceCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:cacheName="resourceCache"/>
</property>
</bean>
<bean id="userCache"
class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:cacheName="userCache"/>
</property>
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache-hibernate.xml">
</bean>
<bean id="userDetailsService" class="cn.shopin.miniweb.service.security.UserDetailServiceImpl"/>
<bean id="securityCacheManager"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
p:transactionManager-ref="transactionManager"
p:proxyTargetClass="true">
<property name="target">
<bean class="com.shopin.modules.security.cache.SecurityCacheManagerImpl"
p:sessionFactory-ref="sessionFactory"
p:resourcCache-ref="resourceCache"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="init*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener"/>
</beans>
本文转自 august 51CTO博客,原文链接:http://blog.51cto.com/august/583737,如需转载请自行联系原作者