我們知道springSecurity 會在用戶登錄的時候獲取用戶的角色權限, 你是一個普通用戶可能沒有管理員擁有的權限。用戶登錄後Authentication 獲取用戶的權限。 不通用戶登錄系統會生成各自Authentication
那麼這個 Authentication 存在哪 呢?服務端?那100萬 個用戶都同時登錄,系統如何區分哪個 Authentication是哪個用戶的?
測試。使用兩個賬號,分布登錄兩個不通浏覽器。一個是火狐,一個是谷歌。控制台分別打印出
==========================兩個角色互不干擾。
這個授權是在調用登錄接口時候驗證的。
我的疑惑是如果是 存在內存裡,內存怎麼識別哪個用戶哪個角色。
其他接口調用,使用AuthUtil 獲取權限的時候, 沒有在去授權
難道存在客戶端的cookie?
現在一個測試浏覽器 兩個窗口打開, 登錄兩個不同的賬號 ,結果不同角色不同權限。
好吧, 開始看源碼吧。
先看我自定義的授權接口:
返回一個UsernamePasswordAuthenticationToken 對象,存儲了用戶名。 密碼。權限
點進去
頂級接口AbstractAuthenticationToken
點進去
AbstractAuthenticationToken 這個抽象類, 實現了兩個接口Authentication // CredentialsContainer
CredentialsContainer 接口點擊進去
CredentialsContainer 谷歌翻譯 憑據容器 難道是所有的授權存在這裡?看了它 的方法, 只有一個, void eraseCredentials(); 清除憑證
=====================先不探究
看下 另一個接口 Authentication
實現了Serializable 接口 。序列化對象。
好吧還是看不懂, 那看獲取權限另一種方式, 不是AuthUtil
看下SecurityContextHolder 源碼
有個靜態方法 initialize();
看下這個方法
第一個 if判斷 返回一個空
strategyName = MODE_THREADLOCAL;
THREADLOCAL 線程局部變量
每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突。
繼續往下面看:
這裡跳轉:
返回一個對象 ThreadLocalSecurityContextHolderStrategy
聲明一個ThreadLocal
存儲的是對象
這裡存了權限。
================================
重點是這個set 方法, 看看被哪些 調用
被七個方法調用:
臥槽,
第一個
看看父類 AbstractSecurityInterceptor 抽象權限過濾器, 應該不是這個時候存進去的。
第二個
DelegatingSecurityContextCallable 委派權限上下文對象, 看著也不像。
第三個
谷歌翻譯 是消化授權過濾器, 應該不是這個時候存的
第四個
權限上下文持久化過濾器
看到持久化,趕緊點進去==》
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為每個使用該變量的線程提供獨立的變量副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本。
======================================================源碼太多, 有些人說看源碼是一種享受,很少吧