<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring-Security 認(rèn)證流程分析及多方式登錄認(rèn)證實(shí)踐

          共 6415字,需瀏覽 13分鐘

           ·

          2024-08-18 07:34

          閱讀本文大概需要 4 分鐘。

          來(lái)自:juejin.cn/post/7329144188926967860

          推薦一個(gè)程序員編程資料站:
          http://cxyroad.com

          2024年IDEA最新激活方法
          后臺(tái)回復(fù):激活碼

          CSDN免登錄復(fù)制代碼插件下載:
          CSDN復(fù)制插件

          以下是正文。




          1 前言

          在項(xiàng)目開(kāi)發(fā)過(guò)程中,會(huì)涉及到安全框架的配置。其中常用的就是 shiro 和 spring-security,在本文中將介紹 spring-security 的工作流程和實(shí)踐應(yīng)用,并基于此總結(jié)其使用心得和項(xiàng)目配置關(guān)鍵。

          2 spring security 認(rèn)證和權(quán)限流程

          圖片
          如上圖所示,一個(gè)請(qǐng)求在達(dá)到控制器之前,會(huì)經(jīng)過(guò)一系列的過(guò)濾器 DefaultSecurityFilterChain,綠色的部分負(fù)責(zé)用戶認(rèn)證,藍(lán)色的部分處理認(rèn)證異常的情況,橙色的部分負(fù)責(zé)用戶的授權(quán),最終請(qǐng)求到控制器的方法。在認(rèn)證完成之后,會(huì)將用戶認(rèn)證的結(jié)果 Authentication 放進(jìn) SecurityContextHolder 中,從中可以獲取到用戶信息。
          在開(kāi)始之前,需要先介紹一下其他重要的組件
          • SecurityContextHolder: 存放身份信息的容器
          • Authentication: 用戶信息的抽象即 security 的認(rèn)證主體
          • AbstractAuthenticationToken: authentication 即認(rèn)證主體的抽象類,
          • AuthenticationManager 身份認(rèn)證器接口,具體實(shí)現(xiàn)類為 ProviderManager
          • AuthenticationProvider 用來(lái)處理 authentication 的認(rèn)證信息
          • AuthenticationSuccessHandler 認(rèn)證成功處理器
          • AuthenticationFailureHandler 認(rèn)證失敗處理器
          認(rèn)證的流程如下所示:
          1、用戶請(qǐng)求的接口經(jīng)過(guò) security 過(guò)濾器,按照其登錄方式適配的 authentication 封裝其認(rèn)證方法,通過(guò) AuthenticationProvider 來(lái)進(jìn)行處理認(rèn)證。獲取身份信息會(huì)按照其配置provider的順序來(lái)處理。
          2、通常情況下將身份信息封裝到封裝成Authentication下的實(shí)現(xiàn)類UsernamePasswordAuthenticationToken, 通常是用戶密碼的登錄方式。
          3、通過(guò) AuthenticationManager 身份管理器,通過(guò)其配置的provider 驗(yàn)證這個(gè)UsernamePasswordAuthenticationToken 的信息。
          4、認(rèn)證邏輯一般是在 service 中,認(rèn)證成功之后會(huì)返回認(rèn)證信息,AuthenticationManager.authentication身份管理器返回一個(gè)Authentication實(shí)例(上下文中包含權(quán)限信息,身份信息,細(xì)節(jié)信息,但是密碼會(huì)被移除)。
          5、SecurityContextHolder 上下文容器會(huì)填充UsernamePasswordAuthenticationToken信息,通過(guò) SecurityContextHolder.getContext().setAuthentication()方法可以查看其上下文用戶信息。
          上述流程具體來(lái)說(shuō),如下圖所示:
          圖片

          3 spring security 登錄配置

          通常情況下,都是用戶名和密碼表單的方式進(jìn)行登錄,同時(shí)在登錄時(shí)還會(huì)添加動(dòng)態(tài)驗(yàn)證碼和自動(dòng)登錄的方式,具體如下圖所示:
          圖片
          核心配置如下所示:
          1、攔截認(rèn)證請(qǐng)求配置,這里需要配置不需要登錄就可以訪問(wèn)的資源,包括登錄頁(yè)面、請(qǐng)求提交頁(yè)面,靜態(tài)資源等內(nèi)容。
          • 登錄請(qǐng)求不攔截 permitAll
          • 資源需要某些角色 hasRole
          • 資源訪問(wèn)需要某些權(quán)限 hasAuthority
          • 其它的資源需要經(jīng)過(guò)認(rèn)證,在資源權(quán)限上的配置也可以通過(guò)注解的方式在控制器中設(shè)置
          2、登錄頁(yè)面配置,需要配置登錄請(qǐng)求的參數(shù),登錄頁(yè)面,登錄訪問(wèn)路徑以及成功和失敗的處理器,這里需要注意的是,successForwardUrl 是請(qǐng)求轉(zhuǎn)發(fā)的方式,defaultSuccessUrl是重定向的方式。
          3、退出的配置,這里需要配置的是退出的地址以及session 和 authentication 的處理。
          4、session 的管理,通常情況下在前后端不分離的情況下,需要用 session 進(jìn)行管理,在前后端分離的情況下,一般通過(guò) token 的方式來(lái)存儲(chǔ)用戶信息。maximumSessions 表示最大的用戶登錄數(shù)量。
          5、在處理異常的情況時(shí),配置異常信息的處理器,通常是錯(cuò)誤頁(yè)或者返回錯(cuò)誤信息,accessDeniedHandler 即權(quán)限異常處理器
          6、在登錄時(shí),還會(huì)有記住我的選項(xiàng),需要配置 token 的配置信息,以及記住我的參數(shù)信息。
          7、csrf/cors/frameoptions/cache 的配置方式。
          8、此外還會(huì)有 addFilterAt/addFilterAfter/addFilterBefore 的方式來(lái)處理自定義的過(guò)濾器。
          圖片
          spring-security 的其它配置如下所示,可以配置信息提示的國(guó)際化,身份認(rèn)證的方式,自定義 AuthenticationManager,以及配置token 的持久化方式,這里包括內(nèi)存方式和數(shù)據(jù)庫(kù)方式。
          圖片
          如果登錄需要配置驗(yàn)證碼的方式,則需要配置驗(yàn)證碼的方式,這里需要處理圖片驗(yàn)證碼。配置密碼處理器,這里為了方便起見(jiàn),使用的是明文密碼。資源的配置可以配置靜態(tài)資源的方式,來(lái)配置靜態(tài)資源和某些接口的訪問(wèn)權(quán)限。
          圖片
          KaptchaFilter 是用來(lái)配置驗(yàn)證碼的處理,通常情況下登錄需要需要 post 的方式,對(duì)于驗(yàn)證碼的處理方式,需要先生成驗(yàn)證碼存儲(chǔ)到內(nèi)存中,然后登錄時(shí)需要攜帶驗(yàn)證碼參數(shù)來(lái)進(jìn)行校驗(yàn)而后進(jìn)行下一個(gè)過(guò)濾器處理。
          圖片
          最后,需要注意的是,在設(shè)置登錄后成功的主頁(yè)面時(shí),如果配置的是請(qǐng)求轉(zhuǎn)發(fā)的方式,其訪問(wèn)方式需要和登錄處理器的 http method 保持一致。

          4 spring security 表單認(rèn)證流程

          通過(guò)上述的表單認(rèn)證配置,通過(guò)源碼分析可以得知如下的表單認(rèn)證流程,具體如下圖所示:
          圖片
          1、SecurityContextPersistenceFilter 攔截所有的請(qǐng)求,共享會(huì)話將 session 中的 SecurityContext 信息放進(jìn)線程上下文中。
          2、AbstractAuthenticationProcessingFilter 判斷是否需要認(rèn)證,需要認(rèn)證就獲取認(rèn)證 Authentication,然后放進(jìn) session 中。
          3、未認(rèn)證的請(qǐng)求由 UsernamePasswordAuthenticationFilter 創(chuàng)建 UsernamePasswordAuthenticationToken 進(jìn)行認(rèn)證,委托 ProviderManager (即 AuthenticationManager) 發(fā)起認(rèn)證,由多個(gè) AuthenticationProvider 接口列表組成進(jìn)行循環(huán)處理。
          4、DaoAuthenticationProvider 調(diào)用 UserDetailsService 方法進(jìn)行用戶查詢,最終返回 AuthenticationToken 即 UsernamePasswordAuthenticationToken
          5、整個(gè)過(guò)程中出現(xiàn)認(rèn)證失敗情況交由 ExceptionTranslationFilter 進(jìn)行處理
          6、所有的配置攔截規(guī)則在 FilterSecurityInterceptor 中體現(xiàn),判斷用戶是否有權(quán)限訪問(wèn)資源。

          5 手機(jī)號(hào)和郵箱驗(yàn)證碼登錄

          通過(guò)以上的分析,已經(jīng)明晰了 spring security 認(rèn)證相關(guān)的內(nèi)容,通常情況下,系統(tǒng)的登錄不僅有賬號(hào)密碼登錄,還有手機(jī)號(hào)驗(yàn)證碼、第三方授權(quán)等登錄多種方式,在接下來(lái)將要介紹的就是手機(jī)號(hào)驗(yàn)證碼登錄和郵箱登錄的方式。
          接下來(lái)將要重點(diǎn)介紹的如下:
          • 繼承 AbstractAuthenticationProcessingFilter,重寫 attemptAuthentication 用于獲取登錄提交參數(shù),并校驗(yàn)驗(yàn)證碼是否正確
          • 繼承 AuthenticationProvider,重寫 authenticate 方法,從數(shù)據(jù)庫(kù)查詢用戶信息,并完成 AuthenticationToken 對(duì)象封裝。
          • 繼承 AbstractAuthenticationToken, 重寫構(gòu)造方法,完成對(duì)象封裝以及授權(quán)。
          如下圖所示,完成如下配置即可完成手機(jī)號(hào)驗(yàn)證碼登錄的功能。
          圖片
          核心的兩處代碼如下圖所示:參數(shù)的獲取以及請(qǐng)求的token 封裝認(rèn)證。
          圖片
          用戶認(rèn)證成功后封裝用戶信息。
          圖片
          除此之外,還有發(fā)送驗(yàn)證碼的接口,通常驗(yàn)證碼會(huì)存儲(chǔ)在 redis 中,通過(guò)憑證來(lái)從緩存中獲取并校驗(yàn)。
          圖片
          手機(jī)號(hào)登錄流程如下:
          1. 調(diào)用發(fā)送驗(yàn)證碼接口,發(fā)送驗(yàn)證碼,本例是在控制臺(tái)打印驗(yàn)證碼。
          2. 通過(guò)表單或者json格式都可以提交信息完成認(rèn)證。
          3. 用戶認(rèn)證成功或者失敗時(shí),通過(guò)認(rèn)證成功或者失敗處理器進(jìn)行處理,返回 json 數(shù)據(jù)格式或者是頁(yè)面。
          終于搞懂了spring security 相關(guān)的認(rèn)證流程和認(rèn)證成功的處理方式,此外,還可以通過(guò)如下方式,通過(guò)注入 AuthenticationManager 調(diào)用認(rèn)證方式來(lái)處理用戶認(rèn)證信息。
          圖片

          6 總結(jié)

          本文主要介紹了 spring security 登錄相關(guān)的核心配置,以及驗(yàn)證碼方式登錄的實(shí)踐, spring security 作為系統(tǒng)開(kāi)發(fā)中常用的權(quán)限認(rèn)證框架,在此基礎(chǔ)上拓展了項(xiàng)目的多種登錄方式,即手機(jī)驗(yàn)證碼和郵箱驗(yàn)證碼的方式,同時(shí)也介紹了前后端分離與不分離情況下的差異。
          本文總結(jié)了 spring security 常用的使用方式,可以很好的為后續(xù)開(kāi)發(fā)提供借鑒。所涉及的代碼已經(jīng)上傳至 gitee:https://gitee.com/xieyue86/springsecurity-learn
          <END>

          推薦閱讀:

          Java8中一個(gè)極其強(qiáng)悍的新接口,炸裂!很多人沒(méi)用過(guò)

          幾行代碼,搞定 SpringBoot 接口惡意刷新和暴力請(qǐng)求!

               
          程序員在線工具站:cxytools.com

          推薦一個(gè)自己寫的工具站:http://cxytools.com,專為程序員設(shè)計(jì),包括時(shí)間日期、JSON處理、SQL格式化、隨機(jī)字符串生成、UUID生成、文本Hash...等功能,提升開(kāi)發(fā)效率。

          ?戳閱讀原文直達(dá)!                                  朕已閱 

          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲日韩中文在线观看 | 国产精品自拍XXX | 亚洲男人在线观看天堂 | 国产探花在线观看 | 国产一级特黄 |