SpringSecurity的認證實現分析

實現機制

概括來講,是將認證信息放在Session中,當客戶端發起訪問時檢查Session中是否存在認證信息,以及認證信息中的權限是否滿足預期。
更具體地說,是通過Filter來攔截客戶端請求並進行判斷處理,使用的Filter鏈如下:

[
org.springframework.security.web.context.SecurityContextPersistenceFilter, 
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter, 
org.springframework.security.web.header.HeaderWriterFilter, 
org.springframework.security.web.authentication.logout.LogoutFilter, 
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter, 
org.springframework.security.web.authentication.www.BasicAuthenticationFilter, 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter, 
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter, 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter, 
org.springframework.security.web.session.SessionManagementFilter, 
org.springframework.security.web.access.ExceptionTranslationFilter, 
org.springframework.security.web.access.intercept.FilterSecurityInterceptor
]

值得注意的是:這些Filter都是Spring Security框架中定義的,它們會被加載到Spring容器中,最終會被包裝到FilterChainProxy$.VirtualFilterChainadditionalFilters屬性中。

那麼這些Filter是如何生效的呢?

與普通的Sevlet Filter不同,這些Filter不需要在web.xml中明確配置,但是需要在web.xml中配置org.springframework.web.filter.DelegatingFilterProxy作爲進入Spring Security框架的入口。

<!-- 集成Spring Security框架 -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

DelegatingFilterProxy的執行路徑如下:
org.springframework.web.filter.DelegatingFilterProxy.doFilter()
->org.springframework.security.web.FilterChainProxy.doFilter() -> doFilterInternal()
->org.springframework.security.web.FilterChainProxy$.VirtualFilterChain.doFilter()

最後是在org.springframework.security.web.FilterChainProxy$.VirtualFilterChain.doFilter()方法中依次取出additionalFilters屬性中的Filter對象執行攔截操作。

認證流程

如上所述,Spring Security的認證實現都是通過Filter攔截來實現的,最終是在org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication()方法中實現的。
具體的執行流程圖如下:
SpringSecurity登錄認證流程

默認情況下,Spring Security處理登錄認證的URI地址爲/login,且只支持POST方法,這可以從UsernamePasswordAuthenticationFilter的構造函數中得到確認。

public UsernamePasswordAuthenticationFilter() {
    super(new AntPathRequestMatcher("/login", "POST"));
}

也就是說在<security:form-login>中指定的login-processing-url屬性實際上必須是/login,同時也必須把自定義登錄頁面表單中的action屬性也設置爲login

當然,Spring Security處理登錄認證的URI地址是可以修改的,如下所示在<security:form-login>中修改:

<!--授權自定義登錄頁-->
<security:form-login login-processing-url="/lg">

特別注意:如果修改了默認認證地址URI,則必須同步修改自定義登錄頁面表單中的action屬性值。

【參考】
java筆記----springMvc簡單整合spring-security示例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章