最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Security過濾器鏈加載執(zhí)行流程源碼解析

 更新時(shí)間:2021年12月31日 17:14:12   作者:Charge8  
Spring?Boot?對(duì)于?Spring?Security?提供了自動(dòng)化配置方案,可以使用更少的配置來使用?Spring?Security。那么這個(gè)過濾器鏈?zhǔn)窃趺醇虞d和實(shí)現(xiàn)攔截的呢,對(duì)Spring?Security過濾器鏈加載執(zhí)行流程感興趣的朋友一起看看吧

Spring Security實(shí)現(xiàn)原理

Spring Security 采用 IoC 和 AOP思想,基于 Servlet 過濾器實(shí)現(xiàn)的安全框架、為 Web 請(qǐng)求和方法調(diào)用提供身份確認(rèn)和授權(quán)處理,還提供與其他庫的集成以簡(jiǎn)化其使用,避免了代碼耦合,減少了大量重復(fù)代碼工作。

在之前 web.xml中,我們是這樣寫的。

<!--SpringSecurity核心過濾器鏈-->
    <!--springSecurityFilterChain名詞不能修改-->
    <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>

在 Spring Boot項(xiàng)目之后,我們引入 Spring Security依賴,什么也沒做,啟動(dòng)項(xiàng)目 Spring Security 就會(huì)生效,訪問請(qǐng)求就進(jìn)行了攔截。

Spring Boot 對(duì)于 Spring Security 提供了自動(dòng)化配置方案,可以使用更少的配置來使用 Spring Security。
那么這個(gè)過濾器鏈?zhǔn)窃趺醇虞d和實(shí)現(xiàn)攔截的呢?

一、Spring Security過濾器鏈加載

1、注冊(cè)名為 springSecurityFilterChain的過濾器

當(dāng) Spring Boot 項(xiàng)目啟動(dòng)后,SecurityFilterAutoConfiguration類會(huì)加載 DelegatingFilterProxyRegistrationBean注冊(cè)過濾器,名字為 springSecurityFilterChain。

注意:springSecurityFilterChain名字是固定寫死的。

DelegatingFilterProxyRegistrationBean 注冊(cè)成功后,該過濾器就被加載了到了注冊(cè)器中。
注冊(cè)器注冊(cè)了所有的過濾器后,會(huì)為每個(gè)過濾器生成 DelegatingFilterProxy代理對(duì)象并注冊(cè)到 IoC中 。

2、查看 DelegatingFilterProxy類

我們?cè)L問項(xiàng)目,就會(huì)進(jìn)入 DelegatingFilterProxy類的 doFilter方法。

DelegatingFilterProxy類本質(zhì)也是一個(gè) Filter,其間接實(shí)現(xiàn)了 Filter接口,但是在 doFilter中其實(shí)調(diào)用的從 Spring 容器中獲取到的代理 Filter的實(shí)現(xiàn)類。

返回的 FilterChainProxy對(duì)象。
由此可知,DelegatingFilterProxy類通過 springSecurityFilterChain這個(gè)名稱,得到了一個(gè) FilterChainProxy過濾器,最終執(zhí)行的是這個(gè)過濾器的 doFilter方法。

1)驗(yàn)證 springSecurityFilterChain名詞不能修改
查看 initDelegate方法。

3、查看 FilterChainProxy類

FilterChainProxy類本質(zhì)也是一個(gè) Filter,所以查看 doFilter方法。留意該類里面的屬性。

public class FilterChainProxy extends GenericFilterBean {
    private static final Log logger = LogFactory.getLog(FilterChainProxy.class);
    private static final String FILTER_APPLIED =
            FilterChainProxy.class.getName().concat(".APPLIED");
    // 過濾器鏈
    private List<SecurityFilterChain> filterChains;
    private FilterChainProxy.FilterChainValidator filterChainValidator;
    private HttpFirewall firewall;

3.1 查看 doFilterInternal方法。

驚不驚喜?15個(gè)過濾器都在這里了!

3.2 查看 getFilters方法。

原來這些過濾器都被封裝進(jìn) SecurityFilterChain對(duì)象中。

4 查看 SecurityFilterChain接口

SecurityFilterChain類是個(gè)接口,實(shí)現(xiàn)類也只有一個(gè) DefaultSecurityFilterChain類。
DefaultSecurityFilterChain類的構(gòu)造方法,初始化了 List filters,是通過傳參放進(jìn)去的。

過濾器鏈參數(shù)是什么時(shí)候傳入的?

5 查看 SpringBootWebSecurityConfiguration類

創(chuàng)建 Spring Security 過濾器鏈?zhǔn)墙唤o Spring boot 自動(dòng)配置,由 SpringBootWebSecurityConfiguration類創(chuàng)建注入。

查看 WebSecurityConfigurerAdapter類。

然后會(huì)注入 HttpSecurity對(duì)象,HttpSecurity可以理解為 Spring Security 的 http核心配置,存放 Spring Security 中的過濾器鏈、請(qǐng)求匹配路徑等相關(guān)認(rèn)證授權(quán)的重要方法。

然后開始創(chuàng)建 Spring Security 過濾器鏈了,是交給 Spring Boot自動(dòng)配置,一共有 15個(gè)過濾器。
使用 OrderedFilter進(jìn)行代理,并設(shè)置了order屬性。
添加完成后,將這些過濾器再封裝為 DefaultSecurityFilterChain對(duì)象。

最后通過 WebSecurityConfiguration配置加載 springSecurityFilterChain,WebSecurityConfiguration中維護(hù)了securityFilterChains屬性,會(huì)存放過濾器鏈中所有的過濾器。

總結(jié):
Spring boot 通過 DelegatingFilterProxyRegistrationBean注冊(cè)過濾器,名字為 springSecurityFilterChain,并生成 DelegatingFilterProxy代理對(duì)象并注冊(cè)到 IoC中。最終真正調(diào)用 FilterChainProxy過濾器的 doFilter 獲取到 Spring Security 過濾器鏈。

Spring Security的過濾器鏈在底層是封裝在 SecurityFilterChain接口中的。

二、過濾器鏈的執(zhí)行流程

1、調(diào)用 OncePerRequestFilter過濾器

首先進(jìn)入的是 OncePerRequestFilter 過濾器。
OncePerRequestFilter是為了確保一次請(qǐng)求中只通過一次filter,而不需要重復(fù)的執(zhí)行。

會(huì)進(jìn)入 DelegatingFilterProxy代理對(duì)象中 invokeDelegate方法,實(shí)際真正執(zhí)行的是 FilterChainProxy過濾器的 doFilter 方法。

2、查看 FilterChainProxy過濾器

查看 FilterChainProxy過濾器中的 doFilterInternal方法。
然后首先進(jìn)入FilterChainProxy中的 doFilterInternal方法。
doFilterInternal方法中會(huì)調(diào)用 getFilters方法,會(huì)從過濾器鏈中拿出所有的攔截器。

然后創(chuàng)建一個(gè) VirtualFilterChain對(duì)象,一個(gè)虛擬的過濾器鏈,并執(zhí)行其中的 doFilter 方法。使用過濾器對(duì)當(dāng)前請(qǐng)求進(jìn)行層層過濾。

3、查看 FilterSecurityInterceptor過濾器

最后進(jìn)入到 FilterSecurityInterceptor過濾器中,該過濾器是過濾器鏈的最后一個(gè)過濾器,invoke方法中。

先調(diào)用父類的 beforeInvocation方法,之后調(diào)用 filterChain的 doFilter方法,之后調(diào)用父類的 finallyInvocation和afterInvocation方法。

在 beforeInvocation方法中,如果當(dāng)前的請(qǐng)求沒有通過認(rèn)證,會(huì)拋出 Access is denied異常,這個(gè)異常會(huì)被ExceptionTranslationFilter過濾器處理。如果拋出的異常是 AuthenticationException,則執(zhí)行方法sendStartAuthentication方法。
最終調(diào)用 EntryPoint的 commence方法,發(fā)布異常。

三、Spring Security常見過濾器

1、WebAsyncManagerIntegrationFilter

org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter

其主要用于集成 SecurityContext到 Spring異步執(zhí)行機(jī)制中的 WebAsyncManager。

2、SecurityContextPersistenceFilter

org.springframework.security.web.context.SecurityContextPersistenceFilter

其主要是使用 SecurityContextRepository在 session中保存或更新一個(gè)SecurityContext,并將 SecurityContext給以后的過濾器使用,來為后續(xù) filter建立所需的上下文。
SecurityContext中存儲(chǔ)了當(dāng)前用戶的認(rèn)證以及權(quán)限信息。

3、HeaderWriterFilter

org.springframework.security.web.header.HeaderWriterFilter

其主要是向請(qǐng)求的 Header中添加相應(yīng)的信息,可在 http標(biāo)簽內(nèi)部使用 security:headers來控制。

4、CsrfFilter

org.springframework.security.web.csrf.CsrfFilter

csrf又稱跨域請(qǐng)求偽造,SpringSecurity會(huì)對(duì)所有 post請(qǐng)求驗(yàn)證是否包含系統(tǒng)生成的 csrf的 token信息,
如果不包含,則報(bào)錯(cuò)。起到防止csrf攻擊的效果。

5、LogoutFilter

org.springframework.security.web.authentication.logout.LogoutFilter

其主要用于實(shí)現(xiàn)用戶退出,清除認(rèn)證信息。默認(rèn)匹配 URL為 /logout的請(qǐng)求。

6、UsernamePasswordAuthenticationFilter

org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter

其主要用于認(rèn)證操作,默認(rèn)匹配URL為 /login且必須為POST請(qǐng)求。

7、DefaultLoginPageGeneratingFilter

org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter

如果沒有在配置文件中指定認(rèn)證頁面,則由該過濾器生成一個(gè)默認(rèn)認(rèn)證頁面。

8、DefaultLogoutPageGeneratingFilter

org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter

由此過濾器可以生產(chǎn)一個(gè)默認(rèn)的退出登錄頁面

9、BasicAuthenticationFilter

org.springframework.security.web.authentication.www.BasicAuthenticationFilter

此過濾器會(huì)自動(dòng)解析 HTTP請(qǐng)求中頭部名字為 Authentication,且以 Basic開頭的頭信息。

10、RequestCacheAwareFilter

org.springframework.security.web.savedrequest.RequestCacheAwareFilter

通過HttpSessionRequestCache內(nèi)部維護(hù)了一個(gè) RequestCache,用于緩存 HttpServletRequest。

11、SecurityContextHolderAwareRequestFilter

org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter

針對(duì) ServletRequest進(jìn)行了一次包裝,使得 request具有更加豐富的 API。

12、AnonymousAuthenticationFilter

org.springframework.security.web.authentication.AnonymousAuthenticationFilter

當(dāng) SecurityContextHolder中認(rèn)證信息為空,則會(huì)創(chuàng)建一個(gè)匿名用戶存入到 SecurityContextHolder中。
Spring Security為了兼容未登錄的訪問,也走了一套認(rèn)證流程,只不過是一個(gè)匿名的身份。

13、SessionManagementFilter

org.springframework.security.web.session.SessionManagementFilter

其主要用于限制同一用戶開啟多個(gè)會(huì)話的數(shù)量。

14、ExceptionTranslationFilter

org.springframework.security.web.access.ExceptionTranslationFilter

異常轉(zhuǎn)換過濾器位于整個(gè) springSecurityFilterChain的后方,用來轉(zhuǎn)換整個(gè)鏈路中出現(xiàn)的異常。ExceptionTranslationFilter過濾器會(huì)攔截處理 AccessDeniedException和 AuthenticationException并添加到HTTP響應(yīng)中。

15、FilterSecurityInterceptor

org.springframework.security.web.access.intercept.FilterSecurityInterceptor

獲取所配置資源訪問的授權(quán)信息,根據(jù) SecurityContextHolder中存儲(chǔ)的用戶信息來決定其是否有權(quán)限。

到此這篇關(guān)于Spring Security過濾器鏈加載執(zhí)行流程源碼分析的文章就介紹到這了,更多相關(guān)Spring Security過濾器鏈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中String類getBytes()方法詳解與完整實(shí)例

    Java中String類getBytes()方法詳解與完整實(shí)例

    這篇文章主要給大家介紹了關(guān)于Java中String類getBytes()方法詳解與完整實(shí)例的相關(guān)資料,getBytes()是Java編程語言中將一個(gè)字符串轉(zhuǎn)化為一個(gè)字節(jié)數(shù)組byte[]的方法,需要的朋友可以參考下
    2023-10-10
  • Java8中Lambda表達(dá)式使用和Stream API詳解

    Java8中Lambda表達(dá)式使用和Stream API詳解

    這篇文章主要給大家介紹了關(guān)于Java8中Lambda表達(dá)式使用和Stream API的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java8具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • MyBatis如何使用PageHelper實(shí)現(xiàn)分頁查詢

    MyBatis如何使用PageHelper實(shí)現(xiàn)分頁查詢

    這篇文章主要介紹了MyBatis如何使用PageHelper實(shí)現(xiàn)分頁查詢,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java Random.nextInt()方法的具體使用

    java Random.nextInt()方法的具體使用

    這篇文章主要介紹了java Random.nextInt()方法的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java?@Scheduled定時(shí)器用法解析

    Java?@Scheduled定時(shí)器用法解析

    這篇文章主要介紹了Java?@Scheduled定時(shí)器用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Assert.assertEquals的使用方法及注意事項(xiàng)說明

    Assert.assertEquals的使用方法及注意事項(xiàng)說明

    這篇文章主要介紹了Assert.assertEquals的使用方法及注意事項(xiàng)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • java為移動(dòng)端寫接口開發(fā)實(shí)例

    java為移動(dòng)端寫接口開發(fā)實(shí)例

    本篇文章主要介紹了java如何為移動(dòng)端寫接口,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java基本數(shù)據(jù)類型和運(yùn)算符詳解

    Java基本數(shù)據(jù)類型和運(yùn)算符詳解

    這篇文章主要介紹了Java基本數(shù)據(jù)類型和運(yùn)算符,結(jié)合實(shí)例形式詳細(xì)分析了java基本數(shù)據(jù)類型、數(shù)據(jù)類型轉(zhuǎn)換、算術(shù)運(yùn)算符、邏輯運(yùn)算符等相關(guān)原理與操作技巧,需要的朋友可以參考下
    2020-02-02
  • JAVA8?Stream流中的reduce()方法詳解

    JAVA8?Stream流中的reduce()方法詳解

    reduce 操作可以實(shí)現(xiàn)從Stream中生成一個(gè)值,其生成的值不是隨意的,而是根據(jù)指定的計(jì)算模型,這篇文章主要介紹了JAVA8?Stream流中的reduce()方法詳解,需要的朋友可以參考下
    2023-02-02
  • Java連接合并2個(gè)數(shù)組(Array)的5種方法例子

    Java連接合并2個(gè)數(shù)組(Array)的5種方法例子

    最近在寫代碼時(shí)遇到了需要合并兩個(gè)數(shù)組的需求,突然發(fā)現(xiàn)以前沒用過,于是研究了一下合并數(shù)組的方式,這篇文章主要給大家介紹了關(guān)于Java連接合并2個(gè)數(shù)組(Array)的5種方法,需要的朋友可以參考下
    2023-12-12

最新評(píng)論

海淀区| 临泽县| 丽水市| 长治市| 灵武市| 喜德县| 永丰县| 城口县| 长宁县| 晴隆县| 贺兰县| 丹凤县| 房山区| 固原市| 桃园市| 措勤县| 自治县| 贡嘎县| 恩施市| 福安市| 连城县| 新营市| 洪江市| 龙山县| 广灵县| 波密县| 益阳市| 屯留县| 蕉岭县| 穆棱市| 资阳市| 乌拉特前旗| 元阳县| 三门县| 慈利县| 澳门| 徐州市| 永和县| 松滋市| 嘉荫县| 洪江市|