場景:張三是一個(gè)老師网缝,他應(yīng)邀去參加教師節(jié)活動(dòng)(認(rèn)證)去領(lǐng)取教師節(jié)禮物(授權(quán)蚌铜、鑒權(quán))酥筝;李四不是老師构灸,不能參加活動(dòng)(認(rèn)證失敽采唷)番舆。
--Principal接口
--->被認(rèn)證/授權(quán)者咽安。對(duì)應(yīng)現(xiàn)實(shí)中的用戶遂跟,對(duì)現(xiàn)實(shí)中的用戶的抽象负溪,該用戶可能是一個(gè)用戶名透揣,也可能是一個(gè)token(Token可以理解為由原始的基于賬號(hào)密碼的Principal轉(zhuǎn)換的基于一串加密的字符串的Pricipal,本質(zhì)上都是一個(gè)唯一用戶標(biāo)識(shí))川抡,反正就是一個(gè)標(biāo)識(shí)辐真。提供一個(gè)獲取用戶名稱/個(gè)人標(biāo)識(shí)的方法(getName())巡社。(普通自然人張三)
。
--UserDetails
--->用戶的詳細(xì)信息捷犹,代表的是自己業(yè)務(wù)系統(tǒng)(用戶系統(tǒng))的賬號(hào)岭接,對(duì)應(yīng)用戶表。用來比對(duì)密碼楔脯,賬號(hào)等可以實(shí)現(xiàn)Principal接口撩轰,用來當(dāng)做Principal的擴(kuò)展;
--UserDetailService
--->用來查詢用戶詳細(xì)信息的Service昧廷。
--Authentication接口
--->認(rèn)證/授權(quán)后的主體堪嫂。是對(duì)現(xiàn)實(shí)中的用戶加上一些認(rèn)證/授權(quán)信息后形成的對(duì)象的抽象。繼承自Principal木柬,除此之外皆串,還定義了方法:獲取被認(rèn)證者的詳細(xì)信息(getDetail());判斷是否已經(jīng)通過認(rèn)證(isAuthenticated());設(shè)置認(rèn)證結(jié)果(是否通過授權(quán)setAuthenticated())眉枕;獲取身份“憑證”恶复,如密碼等——根據(jù)實(shí)際情況來判斷(getCredentials())。認(rèn)證的目的就是生成這個(gè)實(shí)體.(通過身份驗(yàn)證后的張三齐遵。此時(shí)寂玲,它已經(jīng)從一個(gè)普通自然變成了該活動(dòng)的'嘉賓'了,具有領(lǐng)禮物的權(quán)利,沒通過認(rèn)證的李四就沒能成為嘉賓。)
梗摇。
--AbstractAuthenticationToken抽象類
--->Authentication的最重要抽象實(shí)現(xiàn)類拓哟。除了實(shí)現(xiàn)Authentication接口的方法外,還持有一個(gè)GrantedAuthority列表伶授,用來記錄該用戶具有哪些權(quán)限断序。
--GrantedAuthority接口
--->權(quán)限的抽象。每一個(gè)實(shí)現(xiàn)類就是一個(gè)權(quán)限糜烹,提供一個(gè)獲取權(quán)限標(biāo)識(shí)的方法(getAuthority())违诗。一個(gè)通過認(rèn)證后的用戶就具有若干權(quán)限,即若干該接口的實(shí)現(xiàn)類疮蹦。這些權(quán)限集合保存在授權(quán)后的主體AbstractAuthenticationToken中诸迟,通過getAuthority()方法獲取。(比如教師節(jié)活動(dòng)上愕乎,可以吃水果阵苇,可以領(lǐng)禮物的權(quán)限等)
。注意:SpringSecurity里權(quán)限和角色都用GrantedAuthority封裝感论,通過ROLE_前綴來區(qū)分角色绅项。
以上為“數(shù)據(jù)對(duì)象”,也就是用來承載數(shù)據(jù)的(類似java里的VO)比肄。還有一些類用來執(zhí)行操作快耿,主要為認(rèn)證
和鑒權(quán)
操作(XXXManager,XXXProvider)囊陡,如下:
--AuthenticationManager接口
--->認(rèn)證管理器,用來執(zhí)行具體認(rèn)證邏輯的接口掀亥。該接口提供了一個(gè)authenticate(Authentication var1)方法撞反,用來執(zhí)行具體的認(rèn)證邏輯。入?yún)⑹且粋€(gè)Authentication對(duì)象铺浇,出參也是一個(gè)Authentication對(duì)應(yīng)痢畜,入?yún)?duì)象是原始用戶基本信息(Principal),出參對(duì)象是一個(gè)根據(jù)用戶基本信息認(rèn)證后的對(duì)象鳍侣,包含認(rèn)證結(jié)果等信息。(它就像一個(gè)保安吼拥,用戶輸入他的基本信息倚聚,經(jīng)過保安的認(rèn)證成功后(也可能失敗)凿可,給他一個(gè)通行證惑折。人還是這個(gè)人,多了個(gè)通行證信息)
--RunAsManager
--->另外一種Manager,用另外一個(gè)身份去認(rèn)證枯跑。
--AuthenticationProvider`接口
--->上面提到AuthenticationManager負(fù)責(zé)認(rèn)證惨驶。但他相當(dāng)于一次性認(rèn)證,而在實(shí)際運(yùn)用場景中敛助,整個(gè)認(rèn)證流程可能分為很多環(huán)節(jié)粗卜,形成一個(gè)鏈條。所以每個(gè)環(huán)節(jié)封裝成用一個(gè)AuthenticationProvider實(shí)例纳击。AuthenticationProvider提供了兩個(gè)方法续扔,一個(gè)authenticate(Authentication var1),作用同AuthenticationManager的該方法焕数,還有一個(gè)supports(Class<?> var1)方法纱昧,用來確定該環(huán)節(jié)對(duì)哪些類有效。
--ProviderManager接口
--->繼承AuthenticationManager堡赔,處理多個(gè)認(rèn)證環(huán)節(jié)的AuthenticationManager识脆。書接上文,多個(gè)AuthenticationProvider需要交給一個(gè)Manager統(tǒng)一處理善已,ProviderManager持有一個(gè)AuthenticationProvider集合灼捂,通過遍歷執(zhí)行各個(gè)AuthenticationProvider,AuthenticationManager將認(rèn)證邏輯(authentication(Authentication var1))委托給各個(gè)Provider去執(zhí)行雕拼。只要一個(gè)Provider不成功纵东,就返回認(rèn)證失敗。
--AuthenticationManagerBuilder
--->用來構(gòu)建AuthenticationManager啥寇,指定認(rèn)證元數(shù)據(jù)偎球,包含賬號(hào)密碼等,該數(shù)據(jù)可以從內(nèi)存讀取洒扎,也可以從數(shù)據(jù)庫讀取。(告訴保安衰絮,具備哪些信息和特征的人才能進(jìn)入袍冷,然后保安就根據(jù)這些信息去認(rèn)證(調(diào)用AuthenticationManager.authenticate(Authentication var1)))
--SpringSecurityContext
--->安全上下文容器,用來保存
和獲取
權(quán)限認(rèn)證的一些主體信息猫牡,可以再當(dāng)前安全范圍內(nèi)通過調(diào)用靜態(tài)方法的方式隨時(shí)隨地傳遞Principal信息
胡诗。類比保安部門,所有安保相關(guān)的信息都保存在這里淌友,包括Authentication信息等煌恢。SpringSecurityContext可以通過SpringSecurityContextHolder獲取,同時(shí)它也被保存雜HttpSession中(該保存動(dòng)作由SecurityContextPersistenceFilter執(zhí)行震庭,該過濾器包含在整個(gè)過濾鏈中瑰抵,它除了保存上下文信息外,也負(fù)責(zé)當(dāng)請(qǐng)求完成后清除上下文信息)器联。但是我們一般不從HttpSesstion中獲取二汛,而是從SpringSecurityContext中獲取。
--SpringSecurityContextHolder
--->獲取安全上下文容器的"把手"類比進(jìn)入保安部辦公室鑰匙拨拓,可以通過這個(gè)holder獲得(進(jìn)入)保安部肴颊。
--ExceptionTranslationFilter
--->該過濾器用來檢測Spring Security異常,統(tǒng)一處理各種異常(認(rèn)證異吃祝或者權(quán)限不足)婿着。這些異常通常由各個(gè)攔截器AbstractSecurityInterceptor拋出。
--AuthenticationEntryPoint
--->沒有認(rèn)證直接訪問接口的處理邏輯類幸海。用來處理沒有認(rèn)證時(shí)的情況祟身,一般是跳轉(zhuǎn)到登錄頁面去登錄。
--AccessDecisionManager
--->權(quán)限管理器物独,負(fù)責(zé)檢驗(yàn)是否具有權(quán)限訪問受保護(hù)的資源袜硫。通過decide(Authentication var1, Object var2, Collection<ConfigAttribute> var3)方法校驗(yàn)是否具有權(quán)限。該方法的三個(gè)屬性分別是待鑒權(quán)主體(用戶)挡篓,安全對(duì)象(一個(gè)方法調(diào)用或者一個(gè)web請(qǐng)求)婉陷,配置屬性(配置中指定的需要哪些權(quán)限,當(dāng)然你也可以在decide方法中實(shí)現(xiàn)成不需要這些權(quán)限)官研。
--AbstractSecurityInterceptor
--->攔截器接口秽澳,每個(gè)安全對(duì)象類型(一個(gè)方法調(diào)用或者一個(gè)web請(qǐng)求)都有特定的AbstractSecurityInterceptor 實(shí)現(xiàn)類,用來攔截對(duì)應(yīng)的安全對(duì)象并調(diào)用相關(guān)的Manager去實(shí)現(xiàn)認(rèn)證鑒權(quán)戏羽。
--SecurityMetadataSource
-->用來獲取安全對(duì)象(一個(gè)方法調(diào)用或者一個(gè)web請(qǐng)求)需要的權(quán)限担神,再結(jié)合Principal中保存的用戶權(quán)限信息調(diào)用對(duì)應(yīng)的投票器來決定是否通過鑒權(quán)。