您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring Security框架中的設計模式有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring Security框架中的設計模式有哪些”吧!
1.模板方法模式
Template Pattern(模板方法模式)是一個抽象類公開定義了執行它的方法的模板。它的子類可以按需要重寫方法實現,但調用將以抽象類中定義的方式進行,這是一種行為型模式。
模板方法方式優點如下:
在父類中提取了公共的部分代碼,便于代碼復用和擴展。部分方法是由子類實現的,子類可以通過擴展方式增加相應的功能,符合開閉原則。缺點如下:
對每個不同的實現都需要定義一個子類,導致類的個數增加,系統更加復雜,設計也更加抽象。父類中的抽象方法由子類實現,子類執行的結果會影響父類的結果,增加了代碼理解難度。介紹完模板方法模式,大家可能大概猜到了 Spring Security 中哪些地方用到模板方法模式了。
我舉幾個簡單的例子。
第一個例子是 AbstractUserDetailsAuthenticationProvider 類的設計。大家都知道這個類是用來做驗證的,認證的邏輯在這個方法中都定義好了,但是該類卻定義了兩個抽象方法:
retrieveUser 該方法用戶從數據源中獲取用戶對象。additionalAuthenticationChecks 該方法用來做額外的校驗(登錄憑證的校驗)這兩個抽象方法是在 DaoAuthenticationProvider 中實現的。DaoAuthenticationProvider 的實現就是從數據庫中加載用戶,默認檢驗登錄憑證也都是驗證密碼。
如果你的數據源來自其他地方,或者登錄憑證不是密碼,那么自定義類繼承自 AbstractUserDetailsAuthenticationProvider 并重寫它里邊的這兩個方法即可。
2.責任鏈模式
Chain of Responsibility Pattern(責任鏈模式) ,在這種模式中,通常每個接收者都包含對另一個接收者的引用,如果一個對象不能處理該請求,那么它會把相同的請求傳給下一個接收者,依此類推。在這個過程中,客戶只需要將請求發送到責任鏈上即可,無須關心請求的處理細節和請求的傳遞過程,所以責任鏈將請求的發送者和請求的處理者解耦了。
責任鏈模式優點如下:
降低對象之間的耦合度。增強了系統的可擴展性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序。簡化了對象之間的連接,每個對象只需保持一個指向其后繼者的引用,不需保持其他所有處理者的引用。責任分擔,每個類只需要處理自己該處理的工作,符合類的單一職責原則。缺點如下:
對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性。很明顯,Spring Security 中的過濾器鏈就是一種責任鏈模式。一個請求到達后,被過濾器鏈中的過濾器逐個進行處理,過濾器鏈中的過濾器每個都具有不同的職能并且互不相擾,我們還可以通過 HttpSecurity 來動態配置過濾器鏈中的過濾器(即添加/刪除過濾器鏈中的過濾器)。
具體的代碼在 FilterChainProxy$VirtualFilterChain 中,如下:
那么接下來我們就來看看 VirtualFilterChain:
private static class VirtualFilterChain implements FilterChain {private final FilterChain originalChain;private final List additionalFilters;private final FirewalledRequest firewalledRequest;private final int size;private int currentPosition = 0;private VirtualFilterChain(FirewalledRequest firewalledRequest,FilterChain chain, List additionalFilters) {this.originalChain = chain;this.additionalFilters = additionalFilters;this.size = additionalFilters.size();this.firewalledRequest = firewalledRequest;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response)throws IOException, ServletException {if (currentPosition == size) {if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)+ " reached end of additional filter chain; proceeding with original chain");}// Deactivate path stripping as we exit the security filter chainthis.firewalledRequest.reset();originalChain.doFilter(request, response);}else {currentPosition++;Filter nextFilter = additionalFilters.get(currentPosition - 1);if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)+ " at position " + currentPosition + " of " + size+ " in additional filter chain; firing Filter: ‘"+ nextFilter.getClass().getSimpleName() + "’");}nextFilter.doFilter(request, response, this);}}}VirtualFilterChain 類中首先聲明了 5 個全局屬性,originalChain 表示原生的過濾器鏈,也就是 Web Filter;additionalFilters 表示 Spring Security 中的過濾器鏈;firewalledRequest 表示當前請求;size 表示過濾器鏈中過濾器的個數;currentPosition 則是過濾器鏈遍歷時候的下標。doFilter 方法就是 Spring Security 中過濾器挨個執行的過程,如果 currentPosition == size,表示過濾器鏈已經執行完畢,此時通過調用 originalChain.doFilter 進入到原生過濾鏈方法中,同時也退出了 Spring Security 過濾器鏈。否則就從 additionalFilters 取出 Spring Security 過濾器鏈中的一個個過濾器,挨個調用 doFilter 方法。nextFilter.doFilter 就是過濾器鏈挨個往下走。關于 FilterChainProxy 的介紹,參見:[深入理解 FilterChainProxy【源碼篇】]
3.策略模式
Strategy Pattern(策略模式),它定義了一系列算法,將每一個算法封裝起來,并讓它們可以相互替換。策略模式讓算法獨立于使用它的客戶而變化,也稱為政策模式(Policy)。
策略模式的優點:
策略模式提供了對“開閉原則”的完美支持,用戶可以在不修改原有系統的基礎上選擇具體的策略,也可以靈活地擴展新的策略。策略模式提供了管理相關的策略的方式。策略模式提供了可以替換繼承關系的辦法。使用策略模式可以避免使用多重條件轉移語句。策略模式的缺點:
客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。策略模式將造成產生很多策略類(可以通過使用享元模式在一定程度上減少對象的數量)。Spring Security 中使用策略模式的地方也有好幾個。
第一個就是用戶登錄信息存儲。
在 SecurityContextHolder 中定義登錄用戶信息存儲的方法,就定義了三種不同的策略:
public class SecurityContextHolder {// ~ Static fields/initializers// =====================================================================================
public static final
String MODE_THREADLOCAL =
"MODE_THREADLOCAL";
public static final
String MODE_INHERITABLETHREADLOCAL =
"MODE_INHERITABLETHREADLOCAL";
public static final
String MODE_GLOBAL =
"MODE_GLOBAL";
public static final
String SYSTEM_PROPERTY =
"spring.security.strategy";
private static String strategyName = System.getProperty(SYSTEM_PROPERTY);
private static SecurityContextHolderStrategy strategy;
}用戶可以自行選擇使用哪一種策略!具體參見:[在 Spring Security 中,我就想從子線程獲取用戶登錄信息,怎么辦?]
還有一個就是 session 并發管理。
在 AbstractAuthenticationProcessingFilter#doFilter 方法中,有如下代碼:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {//省略sessionStrategy.onAuthentication(authResult, request, response);//省略}這就是一種策略模式。
Session 并發管理可以參考:
[什么是會話固定攻擊?Spring Boot 中要如何防御會話固定攻擊?][集群化部署,Spring Security 要如何處理 session 共享?]當然,這樣的例子還有很多,我就不一一列舉了。
4.代理模式
Proxy Pattern(代理模式) :給某一個對象提供一個代理,并由代理對象控制對原對象的引用,它是一種對象結構型模式。
代理模式的優點:
一定程度上降低了系統的耦合度。代理對象可以擴展目標對象的功能。代理對象可以保護目標對象。缺點:
在客戶端和真實對象之間增加了代理,可能會導致請求的處理速度變慢。增加了系統復雜度。代理模式在 Spring Security 中最重要的應用就是 Spring Security 過濾器鏈接入 Web Filter 的過程,使用了 Spring 提供的 DelegatingFilterProxy,這就是一個典型的代理模式:
public class DelegatingFilterProxy extends GenericFilterBean {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws ServletException, IOException {
// Lazily initialize the delegate
if necessary.
Filter delegateToUse =
this.delegate;
if (delegateToUse ==
null) {
synchronized (this.delegateMonitor) {
delegateToUse =
this.delegate;
if (delegateToUse ==
null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac ==
null) {
throw new IllegalStateException("No WebApplicationContext found: " +
"no ContextLoaderListener or DispatcherServlet registered?");
}
delegateToUse = initDelegate(wac);
}
this.delegate = delegateToUse;
}
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
}當然還有其他很多地方也用到代理模式,我就不一一列舉了,歡迎小伙伴們留言補充。
5.適配器模式
Adapter Pattern(適配器模式),大家平時用的手機充電器學名叫做電源適配器,它的作用是把 220V 的電壓轉為手機可用的 5V 電壓。所以適配器模式其實也是類似作用,將一個接口轉換成客戶希望的另一個接口,適配器模式使接口不兼容的類可以一起工作。適配器模式又分為類適配器模式、對象適配器模式以及接口適配器模式。
適配器模式的優點:
解耦,通過引入一個適配器類來重用現有的適配者類,而無須修改原有代碼。增加了類的透明性和復用性。具有較好的靈活性和擴展性都。缺點:
由于 Java 不支持多重繼承,一次最多只能適配一個適配者類,而且目標抽象類只能為抽象類,不能為具體類,其使用有一定的局限性。Spring Security 中的適配器模式也是非常多的,例如我們最為常見的 WebSecurityConfigurerAdapter,該類讓兩個原本不相關的 WebSecurity 和 HttpSecurity 能夠在一起工作。
6.建造者模式
Builder Pattern(建造者模式)是將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的對象出來,用戶只需要指定復雜對象的類型和內容就可以構建對象,而不需要知道內部的具體構建細節。
建造者模式優點:
將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象,而客戶端不需要知道產品內部細節。每一個產品對應一個建造者,用戶使用不同的建造者可以創建不同的產品,建造者本身可以輕松修改或者添加。可以更加精細地控制產品的創建過程。缺點:
創建的產品需要有一定的相似性,如果差異過大,則不適合建造者模式。產品本身的復雜度會提高建造者的復雜度。Spring Security 中對于建造者模式的使用也是非常多,例如典型的 AuthenticationManagerBuilder,它想要建造的對象是 AuthenticationManager,對應的建造方法則是 build。一般建造者模式中建造者類命名以 builder 結尾,而建造方法命名為 build()。
7.觀察者模式
Observer(觀察者模式)指多個對象間存在一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并自動更新,觀察者模式也稱為發布-訂閱模式、模型-視圖模式,它是對象行為型模式。
觀察者模式優點:
降低了目標與觀察者之間的耦合關系,兩者之間是抽象耦合關系。缺點:
目標與觀察者之間的依賴關系并沒有完全解除,而且有可能出現循環引用。當觀察者對象很多時,程序執行效率降低。在 Spring 框架中,觀察者模式用于實現 ApplicationContext 的事件處理功能。Spring 為我們提供了 ApplicationEvent 類和 ApplicationListener 接口來啟用事件處理。Spring 應用程序中的任何 Bean 實現 ApplicationListener 接口,都會接收到 ApplicationEvent 作為事件發布者推送的消息。在這里,事件發布者是主題(Subject) 和實現 ApplicationListener 的 Bean 的觀察者(Observer)。
具體到 Spring Security 中,如登錄成功事件發布,session 銷毀事件等等,都算是觀察者模式。
例如 AbstractAuthenticationProcessingFilter#successfulAuthentication 方法:
protected void successfulAuthentication(HttpServletRequest request,HttpServletResponse response, FilterChain chain, Authentication authResult)throws IOException, ServletException {if (logger.isDebugEnabled()) {logger.debug("Authentication success. Updating SecurityContextHolder to contain: "+ authResult);}SecurityContextHolder.getContext().setAuthentication(authResult);rememberMeServices.loginSuccess(request, response, authResult);// Fire eventif (this.eventPublisher != null) {eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));}successHandler.onAuthenticationSuccess(request, response, authResult);}類似還有很多,如 session 銷毀事件等(參見[Spring Security 自動踢掉前一個登錄用戶,一個配置搞定!],我這里就不一一列舉了。
8.裝飾模式
Decorator(裝飾模式)是指在不改變現有對象結構的情況下,動態地給該對象增加一些額外功能的模式。
裝飾模式的優點:
可以靈活的擴展一個類的功能。缺點:
增加了許多子類,使程序變得很復雜。Spring Security 中對于裝飾模式也有許多應用。最典型的就是一個請求在通過過濾器鏈的時候會不停的變,會不停的調整它的功能,通過裝飾模式設計出了請求的許多類,例如:
HeaderWriterRequestFirewalledRequestStrictHttpFirewallSaveToSessionRequestWrapper…等等,類似的很多,就不一一贅述了。
感謝各位的閱讀,以上就是“Spring Security框架中的設計模式有哪些”的內容了,經過本文的學習后,相信大家對Spring Security框架中的設計模式有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。