Spring Security4源碼解讀探尋許可權機制,springsecurity4
我們知道springSecurity 會在使用者登入的時候擷取使用者的角色許可權, 你是一個普通使用者可能沒有管理員擁有的許可權。使用者登入後Authentication 擷取使用者的許可權。 不通使用者登入系統會產生各自Authentication
那麼這個 Authentication 存在哪 呢?服務端?那100萬 個使用者都同時登入,系統如何區分哪個 Authentication是哪個使用者的?
測試。使用兩個帳號,分布登入兩個不通瀏覽器。一個是Firefox,一個是Google。控制台分別列印出
==========================兩個角色互不干擾。
這個授權是在調用登入介面時候驗證的。
我的疑惑是如果是 存在記憶體裡,記憶體怎麼識別哪個使用者哪個角色。
其他介面調用,使用AuthUtil 擷取許可權的時候, 沒有在去授權
難道存在用戶端的cookie?
現在一個測試瀏覽器 兩個視窗開啟, 登入兩個不同的帳號 ,結果不同角色不同許可權。
好吧, 開始看源碼吧。
先看我自訂的授權介面:
返回一個UsernamePasswordAuthenticationToken 對象,儲存了使用者名稱。 密碼。許可權
點進去
頂級介面AbstractAuthenticationToken
點進去
AbstractAuthenticationToken 這個抽象類別, 實現了兩個介面Authentication // CredentialsContainer
CredentialsContainer 介面點擊進去
CredentialsContainer Google翻譯 憑據容器 難道是所有的授權存在這裡?看了它 的方法, 只有一個, void eraseCredentials(); 清除憑證
=====================先不探究
看下 另一個介面 Authentication
實現了Serializable 介面 。序列化對象。
好吧還是看不懂, 那看擷取許可權另一種方式, 不是AuthUtil
看下SecurityContextHolder 源碼
有個靜態方法 initialize();
看下這個方法
第一個 if判斷 返回一個空
strategyName = MODE_THREADLOCAL;
THREADLOCAL 線程局部變數
每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本衝突。
繼續往下面看:
這裡跳轉:
返回一個對象 ThreadLocalSecurityContextHolderStrategy
聲明一個ThreadLocal
儲存的是對象
這裡存了許可權。
================================
重點是這個set 方法, 看看被哪些 調用
被七個方法調用:
臥槽,
第一個
看看父類 AbstractSecurityInterceptor 抽象許可權過濾器, 應該不是這個時候存進去的。
第二個
DelegatingSecurityContextCallable 委派許可權內容物件, 看著也不像。
第三個
Google翻譯 是消化授權過濾器, 應該不是這個時候存的
第四個
許可權上下文持久化過濾器
看到持久化,趕緊點進去==》
response 裡面拿?我記得我授權之後不是扔到response裡面
繼續看下五個
抽象許可權攔截器, 這個更不是了
第六個
上下文進程攔截器。 馬丹還不是。
第七個
委派許可權上下文介面
這個線程好像也不是,現在似乎都很迷糊。
好吧還是研究UsernamePasswordAuthenticationToken
最終找到了,好吧, 這個 就是最終的設定方法了
來看他的源碼:
原來是這樣的。
==============================================================================================================
現在大概明白了 原理:
1 、使用者密碼使用者名稱驗證。
2 、授權通過,會放到threadLocal。
疑惑: 某個使用者調用某個方法,擷取方法,怎麼判斷他就是那個使用者?
多個使用者調用伺服器這段代碼, 擷取不一樣的角色怎麼做到的!!!!
ThreadLocal在Spring中發揮著重要的作用,在管理request範圍的Bean、交易管理、任務調度、AOP等模組都出現了它們的身影,起著舉足輕重的作用。要想瞭解Spring交易管理的底層技術,ThreadLocal是必須攻克的山頭堡壘。
ThreadLocal是什麼
早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal為解決多線程程式的並發問題提供了一種新的思路。使用這個工具類可以很簡潔地編寫出優美的多線程程式。
ThreadLocal很容易讓人望文生義,想當然地認為是一個“本地線程”。其實,ThreadLocal並不是一個Thread,而是Thread的局部變數,也許把它命名為ThreadLocalVariable更容易讓人理解一些。
當使用ThreadLocal維護變數時,ThreadLocal為每個使用該變數的線程提供獨立的變數副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本。
======================================================源碼太多, 有些人說看源碼是一種享受,很少吧