Spring-Security-文檔筆記之認(rèn)證組件

1. 認(rèn)證組件列表

  • SecurityContextHolder
    存儲(chǔ)認(rèn)證過的用戶的詳細(xì)信息
  • SecurityContext
    包含在SecurityContextHolder中, 存儲(chǔ)當(dāng)前已認(rèn)證用戶的信息(Authentication對(duì)象)
  • Authentication
    提供給AuthenticationManager以提供用戶憑證(密碼), 或者當(dāng)前用戶
  • GrantedAuthority
    授予用戶的權(quán)限.
  • AuthenticationManager
    決定調(diào)用哪個(gè)身份認(rèn)證過濾器
  • ProviderManager
    AuthenticationManager最常用的實(shí)現(xiàn).
  • AuthenticationEntryPoint
    用來向客戶端請(qǐng)求憑證(如重定向到登錄頁面, 或返回一個(gè)www-authenticate響應(yīng))
  • AbstractAuthenticationProcessingFilter
    用于進(jìn)行認(rèn)證的基本Filter.

2. SecutiryContextHolder

SecutiryContextHolder用于存儲(chǔ)已認(rèn)證用戶的信息, 它不關(guān)心用戶是如何通過認(rèn)證的, 只要包含一個(gè)值, 則這個(gè)值將被用來作為一個(gè)已認(rèn)證用戶. 這是一個(gè)jvm設(shè)置, 因此其所有方法都是靜態(tài)的.

通過配置指定相關(guān)策略. 其實(shí)現(xiàn)被委托給 SecurityContextHolderStrategy. 策略指定有兩種方法, 一種是系統(tǒng)屬性, 一種是調(diào)用靜態(tài)方法.

其策略有三種:

  • ThreadLocal:
    默認(rèn), 使用一個(gè)ThreadLocal來存儲(chǔ)用戶信息, 因此在同一個(gè)線程中可以獲取到用戶信息.
  • InheritableThreadLocal:
    使用一個(gè)InheritableThreadLocal存儲(chǔ)用戶信息, 可以當(dāng)前線程創(chuàng)建的子線程中也可以獲取到用戶信息.
  • Global:
    全局共享一個(gè)SecurityContext.

獲取用戶信息:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

類圖:


image.png

3. SecurityContext

存儲(chǔ)Authentication對(duì)象.

4. Authentication

在成功調(diào)用AuthenticationManager.authenticate(Authentication)方法后, 用于存儲(chǔ)已認(rèn)證用戶的信息.
如果其authenticated屬性值為false, Spring Security都將會(huì)對(duì)其進(jìn)行驗(yàn)證.

Collection<? extends GrantedAuthority> getAuthorities()用于獲取授予認(rèn)證主體的權(quán)限, 當(dāng)沒有權(quán)限時(shí)應(yīng)返回空集合,而不是null.

Object getDetails()方法用于存儲(chǔ)認(rèn)證請(qǐng)求信息, 如IP地址, 憑證序列號(hào)等.

Object getPrincipal() : 在使用用戶名和密碼登錄驗(yàn)證的請(qǐng)求中, 在認(rèn)證成功之前, 這通常是用戶名, 認(rèn)證成功后, 這通常是一個(gè)UserDetails對(duì)象.

boolean isAuthenticated(): 用于指示AbstractSecurityInterceptor是否將當(dāng)前的Authentication對(duì)象傳遞給AuthenticationManager進(jìn)行身份驗(yàn)證.

5. GrantedAuthority

用于表示用戶所獲取的權(quán)限, 如角色. 如果使用用戶名密碼認(rèn)證, 權(quán)限應(yīng)由UserDetailsService加載.
它用字符串來表示, 以便能進(jìn)行精確匹配.

6. AuthenticationManager

用于處理認(rèn)證請(qǐng)求. 認(rèn)證后會(huì)將用戶信息存儲(chǔ)到SecurityContext中. 其最常用的實(shí)現(xiàn)為ProviderManager.

必須對(duì)以下異常進(jìn)行驗(yàn)證:

  • 如果用戶被禁用,則應(yīng)拋出DisabledException.
  • 如果用戶被鎖定, 則應(yīng)拋出LockedException.
  • 如果憑證錯(cuò)誤, 則必須拋出badcredentialexception。

Authentication authenticate(Authentication authentication) throws AuthenticationException: 如果調(diào)用成功則返回一個(gè)完全填充(包含了較全面的用戶信息)的Authentication對(duì)象.

7. ProviderManager

最常用的AuthenticationManager實(shí)現(xiàn). 它包含一個(gè)AuthenticationProvider集合. 每個(gè)provider對(duì)應(yīng)一種身份驗(yàn)證方式, 因此通過AuthenticationManager可以支持多種身份驗(yàn)證方式. 如果請(qǐng)求沒有相應(yīng)的provider, 則將拋出ProviderNotFoundException.

image.png

ProviderManager遍歷每個(gè)provider, 如果有一個(gè)provider返回非null結(jié)果, 則將不再調(diào)用后續(xù)未調(diào)用的provider.

此外, ProviderManager還可以配置一個(gè)parent, 當(dāng)ProviderManager無法進(jìn)行認(rèn)證時(shí), 可以調(diào)用這個(gè)parent. 這樣可以在有多個(gè)ProviderManager實(shí)例時(shí), 通過parent來處理公共認(rèn)證方式. parent可以是任何AuthenticationManager實(shí)例, 但通常為ProviderManager.

ProviderManager還負(fù)責(zé)在認(rèn)證成功后清除用戶憑證(密碼). 其eraseCredentialsAfterAuthentication屬性值默認(rèn)為true. 這對(duì)于通過緩存用戶信息再進(jìn)行認(rèn)證的場景可能有影響(因?yàn)槊艽a被清除了). 解決方式是設(shè)置eraseCredentialsAfterAuthentication為false.

認(rèn)證事件
可通過AuthenticationEventPublisher來發(fā)布認(rèn)證事件(成功,失敗). 默認(rèn)是一個(gè)Null實(shí)現(xiàn)(不發(fā)布事件). 因此如果需要發(fā)布事件,則需要注入對(duì)應(yīng)的bean(DefaultAuthenticationEventPublisher). ProviderManager的parent通常不需要配置publisher, 因?yàn)閙anager可以對(duì)parent的認(rèn)證結(jié)果發(fā)布相應(yīng)的事件, 從而造成事件 的重復(fù)發(fā)布.

AuthenticationManager類圖:


image.png

7. AuthenticationProvider

定義認(rèn)證方式.

8. AuthenticationEntryPoint

ExceptionTranslationFilter中用來定義認(rèn)證方案. 即返回給客戶端響應(yīng)以要求客戶端提供何種方式的認(rèn)證.

類圖:


image.png

9. AbstractAuthenticationProcessingFilter

身份驗(yàn)證的一個(gè)基礎(chǔ)Filter.


image.png
  1. 用戶提交認(rèn)證請(qǐng)求后, 它將從請(qǐng)求中獲取相關(guān)參數(shù)并創(chuàng)建一個(gè)Authentication對(duì)象(對(duì)象類型取決于其實(shí)現(xiàn)類).
  2. Authentication對(duì)象被傳遞給AuthenticationManager進(jìn)行驗(yàn)證處理.
  3. 如果驗(yàn)證不通過, 將清除SecurityContextHolder; 調(diào)用RememberMeService.loginFail(如果配置了remeberme); 調(diào)用AuthenticationFailureHandler. 如果驗(yàn)證通過, 通知SessionAuthenticationStrategy有一個(gè)新的登錄; 存儲(chǔ)AuthenticationSecurityContextHolder, SecurityContextPersistenceFilter保存這個(gè)SecurityContextHttpSession; 如果配置了remeberme, 調(diào)用RemeberMeService.loginSuccess; ApplicationEventPublisher發(fā)布一個(gè)InteractiveAuthenticationSuccessEvent, 調(diào)用AuthenticationSuccessHandler.

類圖:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市讳窟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌民傻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡匾竿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蔚万,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岭妖,“玉大人,你說我怎么就攤上這事反璃£腔牛” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵淮蜈,是天一觀的道長斋攀。 經(jīng)常有香客問我,道長梧田,這世上最難降的妖魔是什么淳蔼? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任侧蘸,我火速辦了婚禮,結(jié)果婚禮上鹉梨,老公的妹妹穿的比我還像新娘讳癌。我一直安慰自己,他們只是感情好存皂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布晌坤。 她就那樣靜靜地躺著,像睡著了一般旦袋。 火紅的嫁衣襯著肌膚如雪骤菠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天疤孕,我揣著相機(jī)與錄音商乎,去河邊找鬼。 笑死胰柑,一個(gè)胖子當(dāng)著我的面吹牛截亦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柬讨,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼崩瓤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了踩官?” 一聲冷哼從身側(cè)響起却桶,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔗牡,沒想到半個(gè)月后颖系,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辩越,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年嘁扼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黔攒。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡趁啸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出督惰,到底是詐尸還是另有隱情不傅,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布赏胚,位于F島的核電站访娶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏觉阅。R本人自食惡果不足惜崖疤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一秘车、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧戳晌,春花似錦鲫尊、人聲如沸痴柔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咳蔚。三九已至豪嚎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谈火,已是汗流浹背侈询。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糯耍,地道東北人扔字。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像温技,于是被迫代替她去往敵國和親革为。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 本文基于 Spring Security 5.3版本官方文檔 一舵鳞、簡介 Spring Security是一個(gè)提供身...
    慵懶的陽光丶閱讀 610評(píng)論 0 0
  • 原理Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架震檩。它是用于保護(hù)基于Spring...
    MlLance閱讀 574評(píng)論 2 1
  • 簡介 Spring Security:是一個(gè)提供身份驗(yàn)證,授權(quán)和保護(hù)以防止常見攻擊的框架蜓堕。 憑借對(duì)命令式和反應(yīng)式應(yīng)...
    呼呼菜菜閱讀 3,784評(píng)論 1 7
  • Spring Security文檔的The Security Filter Chain一章指出Spring Sec...
    buzzerrookie閱讀 830評(píng)論 0 1
  • 前言 看了網(wǎng)上各種關(guān)于Spring Security原理解析的文章抛虏,大部分都是一上來就貼源碼的,我個(gè)人覺得一來就貼...
    f310ff9ba986閱讀 1,843評(píng)論 1 18