上篇文章說到,mongodb的網絡通訊協定流程。拿到請求對象後,會調用assemblyresonse函數處理。這部分的代碼實在沒什麼章法可言,<code>if-else</code>遍地,實在不怎麼優雅。可以感受到随着需求的增長,很多代碼都是硬套上去的。本篇介紹的是基本的處理請求,基本請求所指的是command指令以外的處理行為。
首先,擷取到線程綁定(threadlocal)client對象,并對權限子產品初始化,更新auth cache中過期或者失效的權限資訊。然後,根據配置記錄diaglog;接着統計操作計數器。接着,調用receivedxxxx函數,執行相關請求,其間會對權限進行判斷。最後,根據slowlog配置,記錄profiling資料。
query為例:
checkauthforquery之後會調用isauthorizedforactionsonnamespace做具體的驗證功能:
isauthorizedforactionsonnamespace函數用來驗證資源和動作的權限合法性,不同的操作都對應自己的一套動作,相關的對應關系總結如下:
op_code
value
receivedxxxx
checkauthforxxxx
actiontype
op_update
2001
receivedupdate
checkauthforupdate
update
op_insert
2002
receivedinsert
checkauthforinsert
createindex/insert
op_query
2004
receivedquery
checkauthforquery
find
op_get_more
2005
receivedgetmore
checkauthforgetmore
listcollections/listindexes/find
op_delete
2006
receiveddelete
checkauthfordelete
remove
op_kill_cursors
2007
receivedkillcursors
checkauthforkillcursors
killcursors
ps:
2003操作代碼已經廢棄,目前是保留字段
command請求也是通過op_query發送過來的,對于command請求,代碼上分之處理,個人不是很喜歡這個混用op_code的風格,也許是偉大的曆史原因造成的
inprog killop unlock 不走以上流程,通過query包封裝傳遞過來後,調用了相應的處理函數處理
command的權限驗證額外說明
所有的actiontype定義在db/auth/action_types.txt中,非常多
主要對action和resource封裝,然後調用_isauthorizedforprivilege完成功能。
簡單介紹下privilege,action就是對資料的操作,比如query,insert都可以歸納為action;resource就是資料集合,可以是collection,也可以是db,那privilege就是action*privilege的組合,一個privilege可以含有多個action,但在privilege次元上,action都隻能與一個(或者表達式)resource組合。privilege的集合可以組合成role概念,友善使用者配置。
這個函數的處理算法是,周遊授權過的所有使用者,和待驗證的resource比較,如果找到,則對比action,所有的action都找到的話,則通過驗證。