本文章摘编、转载需要注明来源 http://write.blog.csdn.net/postedit/8576449
先来配置下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>
<!-- 记住密码功能(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就自己看看源码,放到链条里就可以了