spring security3教程系列--自定义过滤链

本文章摘编、转载需要注明来源 http://write.blog.csdn.net/postedit/8576449


spring security3 网上的教程很多,但基本都是大同小异,大部分都是用标签配置,所以找了点时间看了下源码,我用的spring security3.1版本,使用bean声明的方式配置过滤链,看本文章需要读者对spring security3 有一定程度的了解


先来配置下web.xml,HttpSessionEventPublisher是使用session管理时需要用到的


<!-- spring security -->
	<filter>
		<filter-name>securityFilterChainProxy</filter-name>
		<filter-class>
			org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>securityFilterChainProxy</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


接着我们要配置一条过滤链(值得注意的是这个bean的id要跟web.xml里配置的filter-name要一致才可以)

<!-- 自定义SPRING SECURITY过滤链 -->
	<bean id="securityFilterChainProxy"
		class="org.springframework.security.web.FilterChainProxy">
		<constructor-arg>
			<list>
				<security:filter-chain pattern="/services/**"
					filters="none" />
				<security:filter-chain pattern="/test*" filters="none" />
				<security:filter-chain pattern="/**"
					filters="concurrentSessionFilter,securityContextPersistenceFilter,logoutFilter,usernamePasswordAuthenticationFilter,rememberMeAuthenticationFilter,sessionManagementFilter,anonymousAuthFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
			</list>
		</constructor-arg>
	</bean>

下面我们逐个filter来看

首先是filterSecurityInterceptor,这是资源访问第一个要过的filter,至于这里面的属性注入请看我之前的spring security3 自定义权限管理的那篇文章

<!-- 自定义UserDetailsService认证  -->
	<bean id="userDetailsService"
		class="com.shadow.security.service.UserDetailsServiceImpl" />

	<!-- 自定义资源权限关系认证 -->
	<bean id="accessDecisionManager"
		class="com.shadow.security.service.AccessDecisionManagerImpl" />

	<!-- 自定义资源权限关系集合 -->
	<bean id="securityMetadataSource"
		class="com.shadow.security.service.SecurityMetadataSourceExtendImpl">
		<property name="matcher" value="ant" />
	</bean>

	<!-- 自定义认证管理,资源,权限  -->
	<bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<property name="authenticationManager"
			ref="authenticationManager" />
		<property name="accessDecisionManager"
			ref="accessDecisionManager" />
		<property name="securityMetadataSource"
			ref="securityMetadataSource" />
	</bean>
        
        <!-- 页面标签权限功能依赖 -->
        <bean id="webInvocationFilter"
               class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator">
               <constructor-arg ref="filterSecurityInterceptor" />
        </bean>



然后是异常捕获的filter,里面有两个属性需要注入,authenticationEntryPoint是配置默认跳转的,accessDeniedHandler是配置当检测无权限访问跳转

<!-- 异常处理过滤器 -->
	<bean id="exceptionTranslationFilter"
		class="org.springframework.security.web.access.ExceptionTranslationFilter">
		<property name="authenticationEntryPoint"
			ref="authenticationEntryPoint" />
		<property name="accessDeniedHandler">
			<!-- 拒绝未授权访问跳转 -->
			<bean
				class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
				<property name="errorPage" value="/error/audit.jsp" />
			</bean>
		</property>
	</bean>



然后是sessionManagementFilter,这个过滤器配置是否在登录后重新生成一个session防止伪造攻击

	<!-- SESSION固化保护,以及并发控制 -->
	<bean id="sessionManagementFilter"
		class="org.springframework.security.web.session.SessionManagementFilter">
		<constructor-arg name="securityContextRepository"
			ref="securityContextRepository" />
		<property name="sessionAuthenticationStrategy"
			ref="concurrentSessionControlStrategy" />
	</bean>

	<!-- SESSION并发配置 -->
	<bean id="concurrentSessionControlStrategy"
		class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
		<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
		<property name="maximumSessions" value="1" />
		<property name="exceptionIfMaximumExceeded" value="false" />
	</bean>

	<bean id="sessionRegistry"
		class="org.springframework.security.core.session.SessionRegistryImpl" />

	<!-- SESSION并发处理 -->
	<bean id="concurrentSessionFilter"
		class="org.springframework.security.web.session.ConcurrentSessionFilter">
		<property name="sessionRegistry" ref="sessionRegistry" />
		<property name="expiredUrl" value="/error/timeout.jsp" />
		<property name="logoutHandlers">
			<list>
				<ref bean="logoutHandler" />
			</list>
		</property>
	</bean>


然后是rememberMeAuthenticationFilter,这个过滤器主要是配置记住密码功能

<!-- 记住密码功能(COOKIE方式) -->
	<bean id="rememberMeAuthenticationFilter"
		class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
		<property name="rememberMeServices" ref="rememberMeServices" />
		<property name="authenticationManager"
			ref="authenticationManager" />
	</bean>
	<bean id="rememberMeServices"
		class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
		<property name="userDetailsService" ref="userDetailsService" />
		<property name="parameter" value="rememberMe" />
		<!-- 默认时间604800秒(一个星期) -->
		<property name="tokenValiditySeconds" value="604800" />
		<property name="key" value="springRocks" />
	</bean>
	<bean id="rememberMeAuthenticationProvider"
		class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
		<property name="key" value="springRocks" />
	</bean>


然后是usernamePasswordAuthenticationFilter请参考我之前的spring security3自定义权限管理那篇文章


然后是logoutFilter,这个过滤器主要是做安全注销功能,注入rememberMeServices属性是为了安全退出的时候把记住密码的状态也删除了

<!-- 注销过滤器 -->
	<bean id="logoutFilter"
		class="org.springframework.security.web.authentication.logout.LogoutFilter">
		<constructor-arg value="/logout.jsp" />
		<constructor-arg>
			<array>
				<ref bean="logoutHandler" />
				<ref bean="rememberMeServices" />
			</array>
		</constructor-arg>
		<property name="filterProcessesUrl" value="/logout" />
	</bean>

	<!-- 注销监听器  -->
	<bean id="logoutHandler"
		class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
	</bean>


然后是securityContextPersistenceFilter,这个过滤器是为了持久化SecurityContext实例

<!-- 持久化SecurityContext过滤器 -->
	<bean id="securityContextPersistenceFilter"
		class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
		<property name="securityContextRepository"
			ref="securityContextRepository" />
	</bean>

	<!-- 生成HttpSessionSecurityContextRepository -->
	<bean id="securityContextRepository"
		class="org.springframework.security.web.context.HttpSessionSecurityContextRepository">
		<property name="allowSessionCreation" value="true" />
		<property name="disableUrlRewriting" value="false" />
	</bean>


然后是concurrentSessionFilter,这个过滤器是控制session并发问题

<!-- SESSION并发处理 -->
	<bean id="concurrentSessionFilter"
		class="org.springframework.security.web.session.ConcurrentSessionFilter">
		<property name="sessionRegistry" ref="sessionRegistry" />
		<property name="expiredUrl" value="/error/timeout.jsp" />
		<property name="logoutHandlers">
			<list>
				<ref bean="logoutHandler" />
			</list>
		</property>
	</bean>



然后大致的过滤链就配置好了,对于cas等那些有需要用到的filter就自己看看源码,放到链条里就可以了

上一篇:GO从入门到进阶教程系列 - 研发高性能ORM框架mysql管理多数据源篇


下一篇:2014-07-25 设置Winform窗体滚动条位置