對于各種資料庫軟體,啟用認證的方法都不同,比如PG是在pg_hba.conf中對使用者設定使用啟用密碼認證,而Oracle遠端登入均需要使用密碼認證。Mongodb是在參數中控制是否啟用密碼認證,并且啟用後,對所有使用者生效,并不能像PG一樣對使用者差別對待。需要啟用認證,使用mongod --auth或者在參數檔案中加入authorization: enabled。mongodb的認證分為使用者驗證(client auth)和叢集間認證(internal auth),在複制集中啟用認證需指定keyFile參數,指定後即預設啟用了使用者驗證。
從3.0開始,mongodb預設采用SCRAM加密算法,在3.0以前預設使用MongoDB-CR算法,是以如果資料庫是從2.X版本更新上來的資料庫,可能出現認證機制不相容導緻用戶端無法連接配接資料庫的情況。另外mongodb還支援x.509算法,主要用于加密連接配接中,本人也未使用過,此處不做探讨。
一. 使用者建立及管理
在Mongodb中的使用者是基于資料庫的,不同資料庫中可以存在同名使用者,是以在登入資料庫的時候,需要指定mongo --authenticationDatabase=XX 參數選擇認證資料庫。在生産中,為了規範和便于管理,我們建議将所有使用者都建立在admin庫中。需要注意的是Mongodb預設是沒有建立任何内置使用者的,是以在資料庫執行個體啟用認證前,需要先建立一個超管賬号,然後再重新開機執行個體啟用認證。
——使用者建立
<code>use admin db.createUser({user:"fhtest", pwd:"Ba@31^T2cy",roles:[{role:"read",db:"production"}]});</code>{role:"read",db:"production"},
表示在production庫有read角色,可以看到roles值是一個數組,是以可以具有多個庫的多種角色或者一個庫的多種角色
——使用者授權
——權限回收
——使用者查詢
二. 角色管理
從上面使用者管理的指令可以看到,不管是授權還是回收權限,都是基于角色的,Mongodb不能直接将某個集合或者資料庫的操作權限授予使用者,隻能通過role來進行授權,role可以是系統内置的,也可以是使用者自定義的。
内置角色包括root、dbOwner、clusterAdmin、read、readWrite等,root角色相當于PG的superuser超管權限。在生産環境中,會有給使用者授予所有資料庫讀權限的需求,類似oracle的select any table ,Mongodb中具有all database role,如readAnyDatabase、readWriteAnyDatabase等 ,詳細内置role可檢視官方文檔。
由于不能将對象權限授予使用者,是以當要進行精細的權限控制,内置角色無法滿足需求,就隻能自定義角色。自定義角色裡面可以直接對對象(resource)進行操作(action)的權限,也可以包含某個角色。如:
<code>use admin db.createRole( { role: "myClusterwideAdmin", privileges: [ { resource: { cluster: true }, actions: [ "addShard" ] }, { resource: { db: "config", collection: "" }, actions: [ "find", "update", "insert", "remove" ] }, { resource: { db: "users", collection: "usersCollection" }, actions: [ "update", "insert", "remove" ] }, { resource: { db: "", collection: "" }, actions: [ "find" ] } ], roles: [ { role: "read", db: "admin" } ] }, { w: "majority" , wtimeout: 5000 } )</code>從上面的例子可以看出resource是一個子文檔,包含db和collection,如果為空則表示所有對象,action是一個數組,包含需要授予的操作權限。
當然也可以将role授權給role,使用db.grantRolesToRole() 。
在生産環境中若,經常需要在mongo上執行javascript腳本,并且使用db.eval()調用javascript腳本,則可能出現如下報錯,提示無權限

eval需要所有資源的所有權限,需建立如下角色并授予使用者
<code>db.createRole( { role: "eval_role", privileges: [ { resource: { anyResource: true }, actions: [ "anyAction" ] } ], roles:[] } )</code>
在此,強烈不建議授予此類權限!調用javascript可以使用其他方案,比如load 。