Spring Security Servlet 安全架構
1. 前言
在上一節中,我們演示了如何快速搭建 Spring Security 項目,本節將主要討論 Spring Security 安全框架的組成。
在前文中提到,Spring Security 設計的 Servlet 安全從架構上分為三個層次,分別是「認證」、「鑒權」、「入侵防護」。那 Spring Security 是通過什么方法將安全邏輯應用到 Servlet 項目中呢?答案就是 Servlet 的過濾器機制。
我們知道,在 Servlet 項目中,請求的接收和處理是通過一個一個的過濾器順序執行實現的,過濾器是 Servlet 項目處理請求的基礎。Spring 則通過委托代理的機制,將 Servlet 和 Spring 框架的 ApplicationContext 對象相互連通。Spring Security 借助 Spring 的委托代理插入了安全框架的內容。也就是說,Spring 向 Servlet 工程中插入了一個自己的過濾器,用來擴展出 Spring 的各項功能,Spring Security 又向 Spring 中插入了自己的過濾器,實現了安全功能。
本節主要討論 Spring Security 在 Servlet 項目中的實現思路。
2. Servlet 項目中的過濾器(Filter)
每當客戶端向 Servlet 服務端發起請求,該請求在被 Servlet 執行前,會經過一系列的過濾器,這些過濾器有兩個主要功能:
- 阻止后續過濾器或者 Servlet 的執行;
- 修改 HttpServletRequest 或者 HttpServletResponse 的內容,提供后續的過濾器或者 Servlet 使用。
每一個過濾器的作用都是為了影響后續過濾器的執行,所以 Filter 的執行順序非常重要,而決定它們順序關系的便是過濾器鏈(Filter Chain)。
3. Spring 的過濾器委托代理機制
Spring 提供了一個名為 DelegatingFilterProxy 的過濾器。這個過濾器的作用是連接 Servlet 項目中 Servlet 容器和 Spring 項目的核心上下文對象(ApplicationContext)。Servlet 容器允許對其過濾器做自定義的擴展,DelegatingFilterProxy 將 Spring 的 Bean 過濾器(Bean Filter)插入到 Servlet 的過濾器鏈中執行。
4. Spring Security 安全過濾器
4.1 加入安全過濾器
Spring Security 的 Servlet 支持是通過過濾器鏈代理(FilterChainProxy)對象實現的。FilterChainProxy 同樣也是一個過濾器,被封裝在 Spring 的過濾器委托代理(DelegatingFilterProxy)中。其過程如圖:
4.2 安全過濾器鏈
安全過濾器鏈(SecurityFilterChain)用在 FilterChainProxy 上,其作用是覺得用于處理安全的過濾器們的執行順序。如圖:
安全過濾器鏈(SecurityFilterChain)是注冊在過濾器鏈代理(FilterChainProxy)上的,有以下幾個特點:
- 為所有 Spring Security 支持的 Servlet 指明了起點;
- 對于一些后臺操作,可以提升執行效率;
- 在 Servlet 容器中,過濾器的選擇是由 URL 決定的,如此便可針對不同 URL 指定相互獨立的安全策略。
有時,我們需要對不同的 URL 做不同的安全處理,就可以通過加入多個安全過濾鏈實現,比如上圖中 SecurityFilterChain0 對 /api/**
請求有 3 個安全過濾器處理,SecurityFilterChain1 對 /**
等其他請求有 4 個安全過濾器的處理。每一個安全過濾器鏈都是獨立的、唯一的且不會重復執行的。
5. 小結
本節我們介紹了 Spring Security 安全架構的設計理念,本節主要知識點如下:
- Servlet 項目基于「過濾器」方式實現功能擴展;
- Spring 項目擴展了「Servlet 過濾器」,增加了自己的「過濾器代理」;
- Spring Security 項目擴展了「Spring 過濾器」,在「Spring 過濾器代理」中加入了安全過濾器;
- Spring Security 項目通過構建一系列的「安全過濾器」實現系統的安全保護能力。
下一節將討論 Spring Security 中內置的過濾器作用及其順序。