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

Spring Security注冊過濾器注意事項(xiàng)詳解

 更新時(shí)間:2024年06月04日 08:22:33   作者:江南一點(diǎn)雨  
前兩天和小伙伴聊了 Spring Security+JWT 實(shí)現(xiàn)無狀態(tài)登錄,然后有小伙伴反饋了一個(gè)問題,感覺這是一個(gè)我們平時(shí)寫代碼容易忽略的問題,所以本文給大家介紹了Spring Security注冊過濾器注意事項(xiàng),需要的朋友可以參考下

一 問題復(fù)原

先來說問題吧,在 Spring Security+JWT 登錄中,整體上的思路就是用戶登錄成功之后返回 JWT 字符串,然后以后用戶每次請求都攜帶上 JWT 字符串,服務(wù)端進(jìn)行校驗(yàn),校驗(yàn)通過之后,請求繼續(xù)執(zhí)行。

按照上面的思路,我們的項(xiàng)目中需要有一個(gè) JwtFilter 用來從請求中提取請求傳來的 Jwt 字符串進(jìn)行校驗(yàn),類似下面這樣:

@Component
public class JwtFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        String requestURI = req.getRequestURI();
        if ("/login".equals(requestURI)) {
            //登錄請求,無需校驗(yàn)令牌,請求繼續(xù)執(zhí)行
            filterChain.doFilter(xxx,xxx);
            return;
        }
        //令牌校驗(yàn)
    }
}

然后有一個(gè)小伙伴反饋,在項(xiàng)目中使用了 WebSecurityCustomizer 給 Swagger 相關(guān)的請求都放行了,結(jié)果這些被放行的請求都被 JwtFilter 攔截了,這是咋回事呢?

首先小伙伴們要知道,使用 WebSecurityCustomizer 放行的請求,都不再經(jīng)過 SecurityFilter 了,所以按理不該再被 JwtFilter 攔截了,因?yàn)?JwtFilter 是隸屬于 SecurityFilter 這個(gè)過濾器鏈中的,并非原生的跟 Servlet 平級(jí)的那種 Filter。

但是為什么又?jǐn)r截了呢?

松哥看了下代碼,發(fā)現(xiàn)問題出在 @Component 這個(gè)注解上。

二 原理分析

在 Spring Boot 項(xiàng)目啟動(dòng)的時(shí)候,有一個(gè)環(huán)節(jié)就是把 Spring 容器中所有類型為 Filter 的 Bean 找出來,并且自動(dòng)添加到容器的過濾器鏈條中(注意不是添加到 Spring Security 過濾器鏈中)。

這段代碼的邏輯位于 ServletContextInitializerBeans#addAdaptableBeans 方法中,在該方法中,會(huì)調(diào)用 addAsRegistrationBean 方法完成以上事情:

private <T, B extends T> void addAsRegistrationBean(ListableBeanFactory beanFactory, Class<T> type,
		Class<B> beanType, RegistrationBeanAdapter<T> adapter) {
	List<Map.Entry<String, B>> entries = getOrderedBeansOfType(beanFactory, beanType, this.seen);
	for (Entry<String, B> entry : entries) {
		String beanName = entry.getKey();
		B bean = entry.getValue();
		if (this.seen.add(bean)) {
			// One that we haven't already seen
			RegistrationBean registration = adapter.createRegistrationBean(beanName, bean, entries.size());
			int order = getOrder(bean);
			registration.setOrder(order);
			this.initializers.add(type, registration);
		}
	}
}

可以看到,這里傳入的參數(shù) type 和 beanType 都是 Filter,從 Spring 容器中找到 Filter 類型的 Bean 存入到 initializers 集合中。不過注意,添加到集合中的實(shí)際上是封裝之后的 registration 對象,這個(gè)對象通過 adapter.createRegistrationBean 方法創(chuàng)建出來,在該方法中,由于我們沒有為當(dāng)前過濾器設(shè)置攔截的請求地址,所以默認(rèn)攔截所有請求,攔截規(guī)則是 /*

最后在 ServletWebServerApplicationContext#selfInitialize 方法中遍歷上一步找到的過濾器,并逐個(gè)進(jìn)行配置,相關(guān)代碼如下:

DynamicRegistrationBean#register:

@Override
protected final void register(String description, ServletContext servletContext) {
    //注冊過濾器
	D registration = addRegistration(description, servletContext);
	//省略
}

AbstractFilterRegistrationBean#addRegistration:

@Override
protected Dynamic addRegistration(String description, ServletContext servletContext) {
	Filter filter = getFilter();
	return servletContext.addFilter(getOrDeduceName(filter), filter);
}

可以看到,這最終就是大家熟知的添加過濾器的代碼了。

三 解決方案

找到問題的原因,那么問題就好解決了。

問題的產(chǎn)生,主要是因?yàn)?Spring 自動(dòng)查找容器中所有 Filter 類型的 Bean,并進(jìn)行配置,那么我們的解決方案就是不要把這個(gè) Bean 注冊到 Spring 容器中,即不要添加 @Component 注解,而是直接自己 new 出來就行了,在配置過濾器鏈的時(shí)候,像下面這樣配置即可:

http.addFilterAfter(new JwtFilter(redisTemplate), SecurityContextHolderFilter.class);

經(jīng)過上面這樣配置之后,JwtFilter 就不存在于原生過濾器鏈中了,只是單純的存在于 SecurityFilter 中。

理解了 Spring Security 原理,那么日常開發(fā)中各種奇奇怪怪的情況,我們就都能輕車熟路的解決了。

到此這篇關(guān)于Spring Security注冊過濾器注意事項(xiàng)詳解的文章就介紹到這了,更多相關(guān)Spring Security注冊過濾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot項(xiàng)目沒有mainClass如何實(shí)現(xiàn)打包運(yùn)行

    spring boot項(xiàng)目沒有mainClass如何實(shí)現(xiàn)打包運(yùn)行

    這篇文章主要介紹了spring boot項(xiàng)目沒有mainClass如何實(shí)現(xiàn)打包運(yùn)行,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • feign調(diào)用跳過HTTPS的SSL證書校驗(yàn)配置過程

    feign調(diào)用跳過HTTPS的SSL證書校驗(yàn)配置過程

    Feign默認(rèn)驗(yàn)證SSL證書,若服務(wù)器使用自簽名或內(nèi)部CA證書會(huì)導(dǎo)致連接失敗,解決方法是跳過校驗(yàn),但僅限測試環(huán)境,生產(chǎn)環(huán)境需嚴(yán)格驗(yàn)證以確保安全
    2025-07-07
  • java之this關(guān)鍵字用法實(shí)例分析

    java之this關(guān)鍵字用法實(shí)例分析

    這篇文章主要介紹了java之this關(guān)鍵字用法實(shí)例分析,較為詳細(xì)的講述了Java中this關(guān)鍵字的用法及適用范圍,并附帶實(shí)例程序加以說明,需要的朋友可以參考下
    2014-09-09
  • Spring @Scheduled注解及工作原理

    Spring @Scheduled注解及工作原理

    Spring的@Scheduled注解用于標(biāo)記定時(shí)任務(wù),無需額外庫,需配置@EnableScheduling,設(shè)置fixedRate、fixedDelay或cron,基于TaskScheduler,默認(rèn)使用線程池,可自定義線程數(shù)及名稱以優(yōu)化性能,本文給大家介紹Spring @Scheduled注解的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2025-06-06
  • 解析JavaSe的抽象類和接口

    解析JavaSe的抽象類和接口

    這篇文章主要為大家詳細(xì)介紹了JavaSe的抽象類和接口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java中equals和hashcode用法

    Java中equals和hashcode用法

    `equals`和`hashCode`方法在Java中密切相關(guān),必須保持一致性,如果兩個(gè)對象通過`equals`方法相等,它們的`hashCode`也必須相同,這對于基于哈希的數(shù)據(jù)結(jié)構(gòu)至關(guān)重要,因?yàn)檫@些結(jié)構(gòu)依賴哈希值進(jìn)行快速查找和存儲(chǔ),為了減少哈希沖突
    2025-01-01
  • java無限遞歸遍歷json對象問題

    java無限遞歸遍歷json對象問題

    這篇文章主要介紹了java無限遞歸遍歷json對象問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Mybatis-plus如何開啟二級(jí)緩存

    Mybatis-plus如何開啟二級(jí)緩存

    這篇文章主要介紹了Mybatis-plus如何開啟二級(jí)緩存問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • mybatis實(shí)現(xiàn)子母表樹型列表查詢的示例

    mybatis實(shí)現(xiàn)子母表樹型列表查詢的示例

    本文主要介紹了mybatis實(shí)現(xiàn)子母表樹型列表查詢的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • SpringBoot給類進(jìn)行賦初值的四種方式

    SpringBoot給類進(jìn)行賦初值的四種方式

    這篇文章主要介紹了springboot給類進(jìn)行賦初值的四種方式,并通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08

最新評(píng)論

晋宁县| 松溪县| 石台县| 威宁| 关岭| 含山县| 贵定县| 台安县| 巴南区| 河西区| 微博| 阿鲁科尔沁旗| 曲靖市| 永昌县| 江永县| 日土县| 海林市| 平山县| 吴桥县| 秀山| 朝阳市| 大余县| 广灵县| 北川| 宕昌县| 牡丹江市| 五常市| 盐城市| 九江县| 新巴尔虎右旗| 揭东县| 邹平县| 微山县| 克山县| 潼关县| 万源市| 张北县| 蒙阴县| 石城县| 广汉市| 南京市|