亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring?Security?OAuth?Client配置加載源碼解析

 更新時間:2023年07月26日 10:03:13   作者:用戶bPc1FjG  
這篇文章主要為大家介紹了Spring?Security?OAuth?Client配置加載源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

這一節(jié)我們以前面默認的OAuth2 客戶端集成為例,來了解下配置文件的加載,示例見第二、第三節(jié)。

InMemoryClientRegistrationRepository

假如你沒有看過相關視頻,或者書,但想要自己分析源碼,應該怎么分析?

在分析原理之前,我們一定要找到突破口,否則就會無從下手,突破口就是之前集成Gitee OAuth的配置文件,我們分析任何框架的源碼都是如此,從表象到骨髓,一層層深入。

spring:
  security:
    oauth2:
      client:
        registration:
          gitee:
            client-id: gitee-client-id
            client-secret: gitee-client-secret
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
            client-name: Gitee
          github:
            client-id: b4713d47174917b34c28
            client-secret: 898389369c2e9f3d1d0ff4543ba1d9b45adfd093
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize
            token-uri: https://gitee.com/oauth/token
            user-info-uri: https://gitee.com/api/v5/user
            user-name-attribute: name

我們點進去,內部就是一個 OAuth2ClientProperties 類,這個類配置了 @ConfigurationProperties 注解用來加載配置文件,用IDE查找一下該類用在了哪些地方,出來很多類,在這種沒法一下判斷的情況下,我的辦法就是一個個進去看,判斷哪個類最有可能,Reactive開頭的類都是在響應式環(huán)境下使用的,都可以忽略。

這里 OAuth2ClientRegistrationRepositoryConfiguration 就是我們要找的類,在該類中會加載一個 InMemoryClientRegistrationRepository Bean,該Bean用于本地存儲客戶端注冊信息的。

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(OAuth2ClientProperties.class)
@Conditional(ClientsConfiguredCondition.class)
class  OAuth2ClientRegistrationRepositoryConfiguration  { 
    @Bean
    @ConditionalOnMissingBean(ClientRegistrationRepository.class)
    InMemoryClientRegistrationRepository clientRegistrationRepository(OAuth2ClientProperties properties) { 
        List<ClientRegistration> registrations = new ArrayList<>(
                OAuth2ClientPropertiesRegistrationAdapter.getClientRegistrations(properties).values());
        return new InMemoryClientRegistrationRepository(registrations);
    }
}

配置

這里有如下幾個配置:

  • @Configuration(proxyBeanMethods = false):使用@Bean時候的配置,proxyBeanMethods表示是否使用代理來獲取bean,這里表示不使用代理獲取,這樣配置能夠提高Spring 的加載速度。
  • @EnableConfigurationProperties:開啟 OAuth2ClientProperties Spring Bean
  • @Conditional(ClientsConfiguredCondition.class): 只有在存在 ClientsConfiguredCondition Bean的時候,才注冊該類

InMemoryClientRegistrationRepository Bean只有在 ClientRegistrationRepository 不存在的時候才會加載。

該Bean的流程是從 OAuth2ClientProperties 配置中獲取OAuth客戶端信息,構建 ClientRegistration 對象,并存儲在 InMemoryClientRegistrationRepository 中。

這個類看似好像到這里就完了,線索斷了嗎,其實沒有,OAuth客戶端配置的加載確實是完成了,那后面其他類肯定會使用到該配置類,這個后面在看,別忘記我們的問題。

回到 OAuth2ClientRegistrationRepositoryConfiguration 所在的目錄,你會發(fā)現該目錄下還有兩個文件 OAuth2ClientAutoConfiguration 和 OAuth2WebSecurityConfiguration ,

看下 OAuth2ClientAutoConfiguration 類,原來 OAuth2ClientRegistrationRepositoryConfiguration 也是由它引導加載的,那么我們看下另外一個類。

OAuth2WebSecurityConfiguration

OAuth2WebSecurityConfiguration 類中,注冊了 InMemoryOAuth2AuthorizedClientService 、 OAuth2AuthorizedClientRepository 、 SecurityFilterChain 。

(1) InMemoryOAuth2AuthorizedClientService 是OAuth2AuthorizedClientService的實現,用于本地保存OAuth2授權客戶端,具有保存已認證的授權客戶端(saveAuthorizedClient)、移除已認證的授權客戶端(removeAuthorizedClient)和獲取已認證的授權客戶端(loadAuthorizedClient)3個功能。

在該類中,你會發(fā)現保存了ClientRegistrationRepository對象,并且loadAuthorizedClient 和 removeAuthorizedClient 的時候,都會調用ClientRegistrationRepository中的findByRegistrationId方法,至此又跟前面加載的InMemoryClientRegistrationRepository聯系在了一起。

(2) AuthenticatedPrincipalOAuth2AuthorizedClientRepository 是OAuth2AuthorizedClientRepository的實現,用于維護 principal 主體(理解為已認證的用戶)與授權客戶端OAuth2AuthorizedClient的關系,并且提供了一個匿名的處理,如果是匿名使用HttpSessionOAuth2AuthorizedClientRepository處理(也可覆蓋提供)。

該類提供了loadAuthorizedClient、saveAuthorizedClient、removeAuthorizedClient、setAnonymousAuthorizedClientRepository 幾個公開方法

(3) SecurityFilterChain :一個過濾器鏈,用來匹配請求,匹配的請求將執(zhí)行一系列過濾器。

@Bean
SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception { 
    http.authorizeRequests((requests)  -> requests.anyRequest().authenticated()); http.oauth2Login(Customizer.withDefaults()); http.oauth2Client();  return http.build();  }

代碼可見,內部使用HttpSecurity構建了一個默認的SecurityFilterChain,表明任何請求都可以使用該過濾器鏈,使用oauth2提供的默認登錄方式(提供一個/login的默認登錄頁面),再最后http.build()用于構建一個SecurityFilterChain,看看此處代碼。

http.build()

build()位于HttpSecurity的父類AbstractSecurityBuilder

public final O build() throws Exception { 
    if (this.building.compareAndSet(false, true)) { 
        this.object = doBuild();
        return this.object;
    }
    throw new AlreadyBuiltException("This object has already been built");
}

build()使用了CAS來保證構建的對象只會構建一次,我們主要看doBuild(),其是一個抽象方法,用于子類去實現具體的構建邏輯,該子類是AbstractConfiguredSecurityBuilder。

protected final O doBuild() throws Exception { 
    synchronized (this.configurers) { 
        //標記構建狀態(tài)
        this.buildState = BuildState.INITIALIZING;
        //加載配置前的處理,默認空實現,子類可以覆蓋實現
        beforeInit();
        //加載配置
        init();
        //修改構建狀態(tài)
        this.buildState = BuildState.CONFIGURING;
        //在開始配置之前的處理
        beforeConfigure();
        //開始配置,調用實現了SecurityConfigurer的configure()
        //在這里會將各種內置的過濾器添加到HttpSecurity中
        configure();
        this.buildState = BuildState.BUILDING;
        //開始構建要返回的對象,抽象返回,子類實現構建邏輯
        O result = performBuild();
        this.buildState = BuildState.BUILT;
        return result;
    }
}

HttpSecurity的構建邏輯

protected DefaultSecurityFilterChain performBuild() { 
    ExpressionUrlAuthorizationConfigurer<?> expressionConfigurer = getConfigurer(
        ExpressionUrlAuthorizationConfigurer.class);
    AuthorizeHttpRequestsConfigurer<?> httpConfigurer = getConfigurer(AuthorizeHttpRequestsConfigurer.class);
    boolean oneConfigurerPresent = expressionConfigurer == null ^ httpConfigurer == null;
    Assert.state((expressionConfigurer == null && httpConfigurer == null) || oneConfigurerPresent,
                 "authorizeHttpRequests cannot be used in conjunction with authorizeRequests. Please select just one.");
    this.filters.sort(OrderComparator.INSTANCE);
    List<Filter> sortedFilters = new ArrayList<>(this.filters.size());
    for (Filter filter : this.filters) { 
        sortedFilters.add(((OrderedFilter) filter).filter);
    }
    return new DefaultSecurityFilterChain(this.requestMatcher, sortedFilters);
}

此處先判斷是否同時加載了ExpressionUrlAuthorizationConfigurer(基于SpEL的URL授權)和AuthorizeHttpRequestsConfigurer(使用AuthorizationManager添加基于 URL 的授權,該類是5.5新增),這兩個不能同時使用。

然后再對加載的過濾器進行Order排序,最后生成DefaultSecurityFilterChain對象返回。

我們可以看下此處filters的值,發(fā)現已經加載了18個filter,如下,其中OAuth2開頭的幾個過濾器特別顯眼。

DisableEncodeUrlFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
OAuth2AuthorizationRequestRedirectFilter
OAuth2LoginAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor

到這里,Spring Security OAuth2 的默認配置已經加載完了,這里描述內容只是我們表象能看到的,其實還有其他的內容,比如HttpSecurity等還有很多。

后面我們將深入分析這18個過濾器都干了哪些事。

要學習一個新框架,我一般會按照如下步驟來實施:

(1)根據官方文檔搭建Demo,先跑起來,有一個整體觀

(2)分析源碼,從Demo的功能配置入手,找到突破口

(3)每次分析源碼,要帶著問題看

(4)根據源碼分析出來的思路,畫架構圖、流程圖

(5)學習框架的實現思路,取其精華去其糟粕

以上就是Spring Security OAuth Client配置加載源碼解析的詳細內容,更多關于Spring Security OAuth Client配置加載的資料請關注腳本之家其它相關文章!

相關文章

  • java使用正則表達式過濾html標簽

    java使用正則表達式過濾html標簽

    本篇文章主要介紹了java正則表達式過濾html標簽,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • 如何使用idea里面自帶的翻譯插件

    如何使用idea里面自帶的翻譯插件

    這篇文章主要介紹了idea里面自帶的翻譯插件,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • JAVA不使用線程池來處理的異步的方法詳解

    JAVA不使用線程池來處理的異步的方法詳解

    這篇文章主要介紹了JAVA不使用線程池來處理的異步的方法,在這個示例中,asyncTask方法創(chuàng)建了一個新的線程來執(zhí)行異步任務,這個新線程會立即開始執(zhí)行,而主線程則會繼續(xù)執(zhí)行后續(xù)的代碼,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 手把手教你用SpringBoot將文件打包成zip存放或導出

    手把手教你用SpringBoot將文件打包成zip存放或導出

    相信各位看官在工作中都會遇到過要把多個文件打包成一個壓縮文件然后導出,或者將文件打包成Zip存放,這就來上代碼,廢話不多說,需要的朋友可以參考下
    2021-06-06
  • Java?項目連接并使用?SFTP?服務的示例詳解

    Java?項目連接并使用?SFTP?服務的示例詳解

    SFTP是一種安全的文件傳輸協(xié)議,是SSH(Secure?Shell)協(xié)議的一個子協(xié)議,設計用于加密和保護文件傳輸的安全性,這篇文章主要介紹了Java?項目如何連接并使用?SFTP?服務的示例詳解,需要的朋友可以參考下
    2025-01-01
  • TransmittableThreadLocal通過javaAgent實現線程傳遞并支持ForkJoin

    TransmittableThreadLocal通過javaAgent實現線程傳遞并支持ForkJoin

    這篇文章主要介紹了TransmittableThreadLocal通過javaAgent實現線程傳遞并支持ForkJoin詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Java經典面試題匯總:Java Web

    Java經典面試題匯總:Java Web

    本篇總結的是Java Web相關的面試題,后續(xù)會持續(xù)更新,希望我的分享可以幫助到正在備戰(zhàn)面試的實習生或者已經工作的同行,如果發(fā)現錯誤還望大家多多包涵,不吝賜教,謝謝
    2021-07-07
  • mybatis插件pageHelper實現分頁效果

    mybatis插件pageHelper實現分頁效果

    這篇文章主要為大家詳細介紹了mybatis插件pageHelper實現分頁效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android應用開發(fā)的一般文件組織結構講解

    Android應用開發(fā)的一般文件組織結構講解

    這篇文章主要介紹了Android應用開發(fā)的一般文件組織結構講解,同時附帶介紹了一個獲取Android的文件列表的方法,需要的朋友可以參考下
    2015-12-12
  • Java編程Commons lang組件簡介

    Java編程Commons lang組件簡介

    這篇文章主要介紹了Java編程Commons lang組件的相關內容,十分具有參考意義,需要的朋友可以了解下。
    2017-09-09

最新評論