#14. Core Security Filter 有不少关键过滤器在spring 安全的项目中老是使用,因此咱们能够查看这些支持的类和接口.想要全面了解,请查看javadoc.html
##14.1 FilterSecurityInterceptorjava
一个典型的配置以下web
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager"/> <property name="accessDecisionManager" ref="accessDecisionManager" /> <property name="securityMetadataSource"> <security:filter-security-metadata-source> <security:intercept-url pattern="/secure/super/**" access="ROLE_WE_DONT_HAVE"/> <security:intercept-url pattern="/secure/**" access="ROLE_SUPERVISOR,ROLE_TELLER"> </property>
FilterSecurityInterceptor主要保护http资源的安全.它要求一个AuthenticationManager和一个AccessDecisionManager的引用.它也提供了一些配置属性来适应不一样的http请求.spring
FilterSecurityInterceptor能够经过两种方式来配置属性.第一个,如上所述,使用<filter-security-metadata-source>命名空间.它与<http>空间很像,但它的子元素只有pattern,access元素.逗号用来划分不一样http url的配置元素.第二选项是写本身的SecurityMetadataSource,可是这个超出了文本文件的内容.不管何种方法,SecurityMetadataSource用来返回关于单个http url的List<ConfigAttribute>.缓存
filter-security-metadata-source的匹配表达式能够经过request-matcher来设置.默认是ant匹配.安全
<bean id="filterInvocationInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager"/> <property name="accessDecisionManager" ref="accessDecisionManager"/> <property name="runAsManager" ref="runAsManager"/> <property name="securityMetadataSource"> <security:filter-security-metadata-source request-matcher="regex"> <security:intercept-url pattern="\A/secure/super/.*\Z" access="ROLE_WE_DONT_HAVE"/> <security:intercept-url pattern="\A/secure/.*\" access="ROLE_SUPERVISOR,ROLE_TELLER"/> </security:filter-security-metadata-source> </property> </bean>
模式按定义的顺序执行.重要的是指定一些具体模式的顺序在一些模糊模式以前.在咱们的例子中,具体路径"/secure/super"的模式在"/secure/"模式以前.若是反转顺序,那么/secure/模式总会匹配,而/secure/super模式不会执行.restful
14.2 ExceptionTranslationFiltersession
ExceptionTranslationFilter是基于FilterSecurityInterceptor的栈中的.它自己不参与安全拦截,负责处理安全拦截器抛出的异常,并提供合适的http请求.mvc
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter"> <property name="authenticationEntryPoint" ref="authenticationEntryPoint"/> <property name="accessDeniedHandler" ref="accessDeniedHandler"/> <bean/> <bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/login.jsp"/> </bean> <bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl"> <property name="errorPage" value="/accessDenied.htm"/>
###14.2.1 AuthenticationEntryPointapp
当你访问一个收保护的资源而没有认证时,AuthenticationEntryPoint就会被调用.此时你但愿调用的是LoginUrlAuthenticationEntryPoint,它会重定向到不一样的url中.
###14.2.2 AccessDeniedHandler
有时已认证的用户会访问被保护的资源会失败.例如,一个user的用户访问admin的资源,有时是直接用html链接,有时是restful的参数问题.一般须要在web层验证,或在服务层的接口固定调用许可.
若是一个AccessDeniedException被抛出,若是用户已被认证,那么ExceptiontranslationFilter会启用第二种方案,AccessDeniedHandler.通常它会返回403的状态码,另外你能够指定一个错误页面.它能够是简单的"access denied"页面,也能够是jsp,还能够实现本身的接口.
你也能够实现一个自定义的AccessDeniedHandler.
###14.2.3 SavedRequest and the RequestCache Interface 异常转化器的另外一个职责是在调用AuthenticationEntryPoint以前保存当前请求.当用户被认证以后,它容许请求重置.典型的例子,如表单登录.通常它能够经过SavedRequestAwareAuthenticationSuccessHandler进行重定向.
RequestCache的一个做用就是存储和恢复HttpServletRequest实例.当HttpSessionRequestCache被使用时,它会在httpSession中存储请求.RequestCacheFilter的工做就是从缓存中取出已保存的请求,并将它们重定向到原来的url中.
##14.3 SecurityContextPersistenceFilter 基本配置以下:
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
它的职责是存储http请求之间的securityContext内容,并在请求完成以后清空SecurityContextHolder.若是不清空ThreadLocal,当它被容器线程池回收时,关于用户的上下文信息就会一直储存.这个线程可能会在之后的阶段使用错误的认证信息继续执行.
14.3.1 SecurityContextRepository
spring security 3.0,负载和存储security上下文是由一个单独的策略接口完成的:
public interface SecurityContextRepository{ SecurityContext loadContext(HttpRequestResponseHolder requestResponseHodler); void saveContext(SecurityContext context,HttpServletRequest,request,HttpServletResponse response); }
HttpRequestResponseHolder,包含了到来的请求和返回信息,并替换他们.它返回的内容会经过拦截链.
其默认实现是HttpSessionSecurityContextRepository,它将security上下文做为httpSesion的一个属性来存储.重要属性,allowSessionCreation,默认值是true.它容许类在须要存储认证用户上下文时来建立一个session.(只有当认证发生,且上下文内容改变才建立).若是你不想建立session,你须要将属性设为false.
<bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"> <property name='securityContextRepository'> <bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'> <property name='allowSessionCreation' value='false' /> </bean> </property> </bean>
另外,你也可以使用一个NullSecurityContextRepository的实例,一个空的对象实现.这样会阻止安全上下文存储.即便session已经存在. ##14.4 UsernamePasswordAuthenticationFilter form-login元素的配置,有三个方面须要配置
在loginUrlAuthenticationEntryPoint配置登录页的url.就像以前同样,并在ExceptionTranslationFilter中设置
实现登录页(使用 jsp或mvc控制器)
在应用上下文中配置UsernamePasswordAuthenticationFilter的实例
在你的拦截器代理中添加拦截器bean(认真排序)
登录表单包含username和password两个字段,默认路径是URl.基本的拦截器配置以下:
<bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"/> </bean>
###14.4.1 认证成功或失败的流向
成功或失败都是有AuthenticationSuccessHandler或AuthenticationFailureHandler策略接口分别决定的.如今有SimpleUrlAuthenticationSuccessHandler,SaveRequestAwareAuthenticationSuccessHandler,SimpleUrlAuthenticationFailureHandler,ExceptionMappingAuthenticationFailureHandler and DelegatingAuthenticationFailureHandler.能够查看文档了解更多.
若是认证成功,则AuthenticationSuccessHandler会调用,并重定向到合适的目的地.默认是使用SavedRequestAwareAuthenticationSuccessHandler,登录成功后会重定向到原始目的地.