Security工作流程及代碼分析

Spring Security工作原理

在瞭解了Security幾個核心類的概念之後,我們梳理一下Security的工作原理。

本文將要分析的幾個問題

security的工作流程,security的幾個核心過濾器的功能,即什麼時候把Authentication與線程綁定,什麼時候進行認證,什麼時候將Authentication與session關聯,什麼時候將Authentication改變更新到session,什麼時候進行權鑑,沒有認證信息及權限的時候是如何處理的。

工作流程

Filter我們都很熟悉了,其實security就是基於FIlter實現的,它的關鍵類FilterChainProxy的就是一個Filter。

帶Security鑑權框架的系統整體過濾流程如下:

在這裏插入圖片描述

下面具體看看Spring Security Filters有哪些過濾器,跟蹤FilterChainProxy的doFilters方法代碼,發現其調用了doFilterInternal,在getFilters方法裏打個斷點,看看有哪些過濾鏈。

在這裏插入圖片描述

根據配置(這個配置的方法之後再講,先把流程理清楚)生成了幾個chain,可以看到一個典型的chain包含filters和requestMatcher,即不同的請求接口會選擇到不同的filters。下面我們來分析幾個主要的Filter。

SecurityContextPersistenceFilter

securityContext指的是認證信息(Authentication,裏面存儲着用戶的信息),這個過濾器實現的功能從兩個角度分析,一是請求進入,而是響應返回,請求進入時,該過濾器使用SecurityContext存儲器(可以是默認的HttpSessionSecurityContextRepository,也可以是根據你的需求自己實現的,這裏講的是默認)從Session中獲取SPRING_SECURITY_CONTEXT_KEY對應的屬性值即SecurityContext,如果獲取得到放入SecurityContextHolder(基於ThreadLocal實現的一個類,用於存儲Authentication)。無論獲取得到還是獲取不到,都進入下一個過濾器。二是從響應返回的方向分析,該過濾器會使用SecurityContext存儲器把securityContext存儲起來。

中間幾個過濾器跳過,其中有一些是我們項目實現的,重要程度不是很高,我們直接看BasicAuthenticationFilter過濾器。

BasicAuthenticationFilter

這個過濾器是基於Basic認證的過濾器,即當用戶使用Basic方式(http的header裏攜帶Authorization: Basic)登錄時纔會使用的過濾器。

在這裏插入圖片描述

當認證失敗,會調用authenticationEntryPoint.commence(request, response, failed)方法進行失敗邏輯處理,並直接return;過濾鏈不再繼續。當認證成功,將Authentication設置進SecrutiyContextHolder,直接進入下一個過濾器(這裏是basicAuthenticationFilter如此,其他認證型的Filter如UserNamePasswordFilter認證成功後會執行sessionStrategy.onAuthentication(authResult, request, response))。

SessionManagementFilter

這個Filter用來處理Session相關的內容有衆多的配置項比如invalidSessionStrategy,sessionAuthenticationStrategy,總而言之,和session相關的都可以在此filter中操作。當securityContext不爲空時會執行SessionAuthenticationStrategy.onAuthentication(authentication, request, response);注意這裏是SessionAuthenticationStrategy比上一個提到的多了個Authentication詞。接着會使用Context存儲過濾器將securityContext存入session中。可以理解爲插入,因爲在響應返回時上面提到的第一個過濾器會進行更新。

ExceptionTranslationFilter

這個是用來處理異常的Filter,看它的doFilter()方法,只是直接到下一個過濾器,然後catch異常,根據異常類型來執行對應操作,這裏只有兩類異常一個是AuthenticationExcepriotn認證異常(沒有認證信息,比如沒帶sessionId),AccessDeniedException權限異常。認證異常會authenticationEntryPoint.commence(request, response, reason);來處理,權限異常會accessDeniedHandler.handle(request, response, (AccessDeniedException) exception);來處理。

在這裏插入圖片描述

FilterSecurityInterceptor

這個過濾器是過濾鏈最後一個過濾器,主要是一個鑑權的作用。它會調用AbstractSecurityInterceptor的beforeInvocation(),如果沒有認證信息則會拋出AuthenticationException,如果有認證信息,但是權限不足則會拋出

AccessDeniedException。這兩個異常會給ExceptionTranslationFilter來處理。

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