核心組件之SecurityContextHolder


作用:保留系統當前的安全上下文細節,其中就包括當前使用系統的用戶的信息。
 
上下文細節怎么表示?
    用SecurityContext對象來表示
 
每個用戶都會有它的上下文,那這個SecurityContext保存在哪里呢?
存儲在一個SecurityContextHolder中,整個應用就一個SecurityContextHolder。
 
SecurityContextHolder存儲SecurityContext的方式?
這要考慮到 應用場景
(1)單機系統,即應用從開啟到關閉的整個生命周期只有一個用戶在使用。由於整個應用只需要保存一個SecurityContext(安全上下文即可)
(2)多用戶系統,比如典型的Web系統,整個生命周期可能同時有多個用戶在使用。這時候應用需要保存多個SecurityContext(安全上下文),需要利用ThreadLocal進行保存,每個線程都可以利用ThreadLocal獲取其自己的SecurityContext,及安全上下文。
 
源碼分析:
SecurityContextHolder結構

 

SecurityContextHolder.java(部分源碼)

 

由源碼可知,SecurityContextHolder利用了一個SecurityContextHolderStrategy(存儲策略)進行上下文的存儲。我們來看看SecurityContestHolderStrategy,到底是什么
 

 

SecurityContestHolderStrategy.java(全部源碼)

 


 

可知 SecurityContestHolderStrategy只是一個接口,這個接口提供創建、清空、獲取、設置上下文的操作。那它有哪些實現類呢,也就是有哪些存儲策略呢?
 
GlobalSecurityContextHolderStrategy.java(全部源碼)
全局的上下文存取策略,只存儲一個上下文,對應前面說的單機系統。
 

 

ThreadLocalSecurityContextHolderStrategy.java(全部源碼)

 

基於ThreadLocal的存儲策略實現,看上去,這個類好像跟上面那個全局的沒什么差別。但是要注意了,它是用ThreadLocal來存儲的。新手可能會疑惑,就一個變量,我怎么存儲多個上下文,這個變量又不是集合。
這里就不分析源碼了,實際上ThreadLocal內部會用數組來存儲多個對象的。原理是,ThreadLocal會為每個線程開辟一個存儲區域,來存儲相應的對象。
 
Authentication——用戶信息的表示:
    在SecurityContextHolder中存儲了當前與系統交互的用戶的信息。Spring Security使用一個Authentication 對象來表示這些信息。一般不需要自己創建這個對象,但是查找這個對象的操作對用戶來說卻非常常見。

 

批注:
    ①Principal(准則)=> 允許通過的規則,即允許訪問的規則,基本等價於UserDetails(用戶信息)
 
源碼分析:
我們來看看,這個SecurityContext(安全上下文),到底是個什么樣子。
SecurityContext.java(全部源碼)

 

由源碼可知,所謂的安全上下文,只是保存了Authentication(認證信息)。那認證信息包含哪些內容呢?
 
Authentication.java(全部源碼)

 

由源碼可知,Authentication(認證信息),主要包含了以下內容
  • 用戶權限集合 => 可用於訪問受保護資源時的權限驗證
  • 用戶證書(密碼) => 初次認證的時候,進行填充,認證成功后將被清空
  • 細節 => 暫不清楚,猜測應該是記錄哪些保護資源已經驗證授權,下次不用再驗證,等等。
  • Pirncipal => 大概就是賬號吧
  • 是否已認證成功
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM