#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,登錄成功後會重定向到原始目的地.