- <?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"/>
- <!-- -->
- <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>
<?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"/>
<!-- -->
<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>