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

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

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

引言

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

InMemoryClientRegistrationRepository

假如你沒有看過相關(guān)視頻,或者書,但想要自己分析源碼,應(yīng)該怎么分析?

在分析原理之前,我們一定要找到突破口,否則就會(huì)無從下手,突破口就是之前集成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

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

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

@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);
    }
}

配置

這里有如下幾個(gè)配置:

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

InMemoryClientRegistrationRepository Bean只有在 ClientRegistrationRepository 不存在的時(shí)候才會(huì)加載。

該Bean的流程是從 OAuth2ClientProperties 配置中獲取OAuth客戶端信息,構(gòu)建 ClientRegistration 對(duì)象,并存儲(chǔ)在 InMemoryClientRegistrationRepository 中。

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

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

看下 OAuth2ClientAutoConfiguration 類,原來 OAuth2ClientRegistrationRepositoryConfiguration 也是由它引導(dǎo)加載的,那么我們看下另外一個(gè)類。

OAuth2WebSecurityConfiguration

OAuth2WebSecurityConfiguration 類中,注冊(cè)了 InMemoryOAuth2AuthorizedClientService 、 OAuth2AuthorizedClientRepository 、 SecurityFilterChain 。

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

在該類中,你會(huì)發(fā)現(xiàn)保存了ClientRegistrationRepository對(duì)象,并且loadAuthorizedClient 和 removeAuthorizedClient 的時(shí)候,都會(huì)調(diào)用ClientRegistrationRepository中的findByRegistrationId方法,至此又跟前面加載的InMemoryClientRegistrationRepository聯(lián)系在了一起。

(2) AuthenticatedPrincipalOAuth2AuthorizedClientRepository 是OAuth2AuthorizedClientRepository的實(shí)現(xiàn),用于維護(hù) principal 主體(理解為已認(rèn)證的用戶)與授權(quán)客戶端OAuth2AuthorizedClient的關(guān)系,并且提供了一個(gè)匿名的處理,如果是匿名使用HttpSessionOAuth2AuthorizedClientRepository處理(也可覆蓋提供)。

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

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

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

代碼可見,內(nèi)部使用HttpSecurity構(gòu)建了一個(gè)默認(rèn)的SecurityFilterChain,表明任何請(qǐng)求都可以使用該過濾器鏈,使用oauth2提供的默認(rèn)登錄方式(提供一個(gè)/login的默認(rèn)登錄頁面),再最后http.build()用于構(gòu)建一個(gè)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來保證構(gòu)建的對(duì)象只會(huì)構(gòu)建一次,我們主要看doBuild(),其是一個(gè)抽象方法,用于子類去實(shí)現(xiàn)具體的構(gòu)建邏輯,該子類是AbstractConfiguredSecurityBuilder。

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

HttpSecurity的構(gòu)建邏輯

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);
}

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

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

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

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

到這里,Spring Security OAuth2 的默認(rèn)配置已經(jīng)加載完了,這里描述內(nèi)容只是我們表象能看到的,其實(shí)還有其他的內(nèi)容,比如HttpSecurity等還有很多。

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

要學(xué)習(xí)一個(gè)新框架,我一般會(huì)按照如下步驟來實(shí)施:

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

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

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

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

(5)學(xué)習(xí)框架的實(shí)現(xiàn)思路,取其精華去其糟粕

以上就是Spring Security OAuth Client配置加載源碼解析的詳細(xì)內(nèi)容,更多關(guān)于Spring Security OAuth Client配置加載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中嵌入式MySQL的使用方法

    Java中嵌入式MySQL的使用方法

    這篇文章主要為大家詳細(xì)介紹了Java中嵌入式MySQL的使用方法,Java中如何使用嵌入MySQL,感興趣的小伙伴們可以參考一下
    2016-11-11
  • java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    這篇文章主要介紹了java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Mybatis-Plus時(shí)間范圍查詢方式詳解

    Mybatis-Plus時(shí)間范圍查詢方式詳解

    這篇文章主要介紹了Mybatis-Plus時(shí)間范圍查詢方式詳解,通過兩種方式結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • java servlet手機(jī)app訪問接口(三)高德地圖云存儲(chǔ)及檢索

    java servlet手機(jī)app訪問接口(三)高德地圖云存儲(chǔ)及檢索

    這篇文章主要為大家詳細(xì)介紹了java servlet手機(jī)app訪問接口(三),高德地圖云存儲(chǔ)及檢索,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • java中XML的使用全過程

    java中XML的使用全過程

    這篇文章主要介紹了java中XML的使用全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Java FileInputStream讀中文亂碼問題解決方案

    Java FileInputStream讀中文亂碼問題解決方案

    這篇文章主要介紹了Java FileInputStream讀中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • springboot實(shí)現(xiàn)配置文件關(guān)鍵信息加解密

    springboot實(shí)現(xiàn)配置文件關(guān)鍵信息加解密

    在項(xiàng)目配置文件中常常會(huì)配置如數(shù)據(jù)庫連接信息,redis連接信息等,連接密碼明文配置在配置文件中會(huì)很不安全,所以本文就來聊聊如何使用springboot實(shí)現(xiàn)配置文件關(guān)鍵信息加解密吧
    2025-05-05
  • Springboot+Shiro+Jwt實(shí)現(xiàn)權(quán)限控制的項(xiàng)目實(shí)踐

    Springboot+Shiro+Jwt實(shí)現(xiàn)權(quán)限控制的項(xiàng)目實(shí)踐

    如今的互聯(lián)網(wǎng)已經(jīng)成為前后端分離的時(shí)代,所以本文在使用SpringBoot整合Shiro框架的時(shí)候會(huì)聯(lián)合JWT一起搭配使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • 一文吃透消息隊(duì)列RocketMQ實(shí)現(xiàn)消費(fèi)冪等原理

    一文吃透消息隊(duì)列RocketMQ實(shí)現(xiàn)消費(fèi)冪等原理

    這篇文章主要介紹了消息隊(duì)列RocketMQ實(shí)現(xiàn)消費(fèi)冪等的全面講解,幫助大家吃透RocketMQ消息隊(duì)列消費(fèi)冪等,更好的的應(yīng)用與工作實(shí)踐,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析

    JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析

    這篇文章主要介紹了JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論

驻马店市| 合阳县| 内江市| 扶沟县| 井冈山市| 乌恰县| 清水河县| 阳曲县| 织金县| 五大连池市| 达日县| 广宗县| 揭西县| 手游| 金溪县| 汪清县| 普兰县| 蓬莱市| 荣昌县| 隆林| 邵东县| 北安市| 靖江市| 宿迁市| 黔西| 城固县| 广丰县| 田东县| 开化县| 毕节市| 平昌县| 改则县| 综艺| 武鸣县| 旬邑县| 公主岭市| 六枝特区| 介休市| 陇川县| 通榆县| 福安市|