MongoDB基礎之 用戶和數據庫基於角色的訪問控制


mongod 關鍵字參數:--auth 

默認值是不需要驗證,即 --noauth,該參數啟用用戶訪問權限控制;當mongod 使用該參數啟動時,MongoDB會驗證客戶端連接的賬戶和密碼,以確定其是否有訪問的權限。如果認證不通過,那么客戶端不能訪問MongoDB的數據庫。

這個參數我們可以寫在配置文件中,表示每次啟動服務都打開auth認證,在這里我們是加在了mongod的啟動指令中,如下所示

[root@:vg_adn_tidbCkhsTest /usr/local/mongodb]#bin/mongo -u "admin" -p "123456" --authenticationDatabase "admin"
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
> db
test

這里的“admin”數據庫是我們在安裝mongo的時候就已經創建的,並且在數據庫中創建了admin用戶,且擁有“userAdminAnyDatabase”角色

下面講解基於角色的訪問控制

角色是授予User在指定資源上執行指定操作的權限,MongoDB官方手冊對角色的定義是:

A role grants privileges to perform the specified actions on resource.

MongoDB為了方便管理員管理權限,在DB級別上預先定義了內置角色;如果用戶需要對權限進行更為細致的管理,MongoDB允許用戶創建自定義的角色,能夠在集合級別上控制User能夠執行的操作。
MongoDB使用角色(Role)授予User訪問資源的權限,Role決定User能夠訪問的數據庫資源和執行的操作。一個User能夠被授予一個或多個Role,如果User沒有被授予Role,那么就沒有訪問MongoDB系統的權限。

A user is granted one or more roles that determine the user’s access to database resources and operations. Outside of role assignments, the user has no access to the system.

1,內置角色(Built-In Roles)

內置角色是MongoDB預定義的角色,操作的資源是在DB級別上。MongoDB擁有一個SuperUser的角色:root,擁有最大權限,能夠在系統的所有資源上執行任意操作。

數據庫用戶角色(Database User Roles):

  • read:授予User只讀數據的權限
  • readWrite:授予User讀寫數據的權限

數據庫管理角色(Database Administration Roles):

  • dbAdmin:在當前dB中執行管理操作
  • dbOwner:在當前DB中執行任意操作
  • userAdmin:在當前DB中管理User

備份和還原角色(Backup and Restoration Roles):

  • backup
  • restore

跨庫角色(All-Database Roles):

    • readAnyDatabase:授予在所有數據庫上讀取數據的權限
    • readWriteAnyDatabase:授予在所有數據庫上讀寫數據的權限
    • userAdminAnyDatabase:授予在所有數據庫上管理User的權限
    • dbAdminAnyDatabase:授予管理所有數據庫的權限

現在我們舉例子介紹一下

上面我們已經創建好了admin用戶,該用戶擁有有grant權限,我們創建的admin用戶是在admin數據庫中創建的。即:賬號管理的授權權限。注意一點,帳號是跟着庫走的,所以在指定庫里授權,必須也在指定庫里驗證(auth)。

由於我們的admin用戶建立了 userAdminAnyDatabase 角色,用來管理用戶,可以通過這個角色來創建、刪除用戶。驗證:需要開啟auth參數

[root@:vg_adn_tidbCkhsTest:23.22.172.65:172.31.22.29 /usr/local/mongodb]#bin/mongo -u "admin" -p "123456" --authenticationDatabase "admin"
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
> db
test
> use admin
switched to db admin
> db
admin
> show users;
{
    "_id" : "admin.admin",
    "user" : "admin",
    "db" : "admin",
    "roles" : [
        {
            "role" : "dbOwner",
            "db" : "test"
        },
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}
> show dbs;
admin  0.000GB
local  0.000GB
test   0.000GB
test1  0.000GB

我們連接上去admin用戶之后,在admin數據庫中就有了權限,注意admin用戶擁有的角色是userAdminAnyDatabase。所以才可以創建用戶等等操作

> use test2                                   #在test2庫中創建賬號
switched to db test2
> db.createUser(
... {
... user:"test",
... pwd:"test",
... roles:[{role:"readWrite",db:"test2"}]
... }
... )
Successfully added user: {
    "user" : "test",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test2"
        }
    ]
}
> show users;
{
    "_id" : "test2.test",
    "user" : "test",
    "db" : "test2",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test2"
        }
    ]
}

現在我們開始驗證一下:

> use test2
switched to db test2> db
test2
> db.abc.insert({"name":"chaofeng","id":1})
WriteResult({
    "writeError" : {
        "code" : 13,
        "errmsg" : "not authorized on test2 to execute command { insert: \"abc\", documents: [ { _id: ObjectId('5bea73410816d4c446c6c0d1'), name: \"chaofeng\", id: 1.0 } ], ordered: true }"
    }
})

因為我目前還是admin登錄的,所以在test2數據庫中,admin用戶沒有權限,只有我們剛剛建立的“test”用戶才有權限。

注意:admin用戶只是擁有了創建用戶,刪除用戶的角色,這並不是最高權限。

所以現在我想在test2數據庫下插入數據,我得使用test用戶才行。

這里還要注意一點:

1、我在admin數據庫中認證test用戶

> db.auth("test","test")
Error: Authentication failed.
0
> db
admin

我在admin數據庫中使用test用戶認,來讓test用戶可以訪問test2數據庫,是失敗的。記住一點:在admin下創建的賬戶,不能直接在admin庫上驗證。

2、我在test2數據庫中認證test用戶

> db.auth("test","test")
1
> db
test2

這樣就成功了,記住一點:在哪個庫上創建的賬戶,就在那里認證,也說明了一點,數據庫賬戶是跟着數據庫走的,先有數據庫,然后才有賬戶去認證這個數據庫,從而有權限操作。

 

現在我們的test用戶已經可以登錄到test2數據庫中操作了,我們嘗試一下

> use test2
switched to db test2> db.abc.insert({"name":"chaofeng","id":1})
WriteResult({ "nInserted" : 1 })
> db.abc.find()
{ "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
> 

 

最后我們再看一下數據庫中創建的所有賬戶

> use admin
switched to db admin> db.system.users.find().pretty()
{
    "_id" : "admin.admin",
    "user" : "admin",
    "db" : "admin",
    "credentials" : {
        "SCRAM-SHA-1" : {
            "iterationCount" : 10000,
            "salt" : "2VmpmkRbVjolDoXjzbjHTw==",
            "storedKey" : "/Rd7OGTHEsGhsK8ZsFGe8DOzHTk=",
            "serverKey" : "8+JA2FBdUVtvo3AZNNDSvREZpOg="
        }
    },
    "roles" : [
        {
            "role" : "dbOwner",
            "db" : "test"
        },
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}
{
    "_id" : "test1.ccf",
    "user" : "ccf",
    "db" : "test1",
    "credentials" : {
        "SCRAM-SHA-1" : {
            "iterationCount" : 10000,
            "salt" : "cqPSk8h1ucAnJEl3mjx8MQ==",
            "storedKey" : "kNNTRqVv63fVy0r1KH9Oem0iKNo=",
            "serverKey" : "yTO6i7IIu7wuTEfd+VJG/l59veM="
        }
    },
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test1"
        }
    ]
}
{
    "_id" : "test2.test",
    "user" : "test",
    "db" : "test2",
    "credentials" : {
        "SCRAM-SHA-1" : {
            "iterationCount" : 10000,
            "salt" : "0K+o35PrySZbdTq0kl79vg==",
            "storedKey" : "z3Z8dDswfQsnJ98qpUG8qChIafQ=",
            "serverKey" : "b6kLZoYhZwgxXmSNLpVIqyr6AyE="
        }
    },
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test2"
        }
    ]
}

查看所有的用戶我們必須在admin數據庫下,在其他的數據中是查看不到的。比如

> use test2
switched to db test2
> db.system.users.find().pretty()

同樣的查看數據庫用戶的指令,在test2數據庫中就不起作用,什么也查不出來。

同樣的道理,當我們登錄到mongo的時候,想要進入到admin庫中查看所有用戶的操作也是需要驗證的,比如:

[root@:vg_adn_tidbCkhsTest /usr/local/mongodb]#bin/mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
> db
test
> use test2
switched to db test2
> use admin
switched to db admin
> db.system.users.find().pretty()
Error: error: {
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { find: \"system.users\", filter: {} }",
    "code" : 13,
    "codeName" : "Unauthorized"
}
> 

緊接着這里我們還沒有在test2庫中認證賬戶密碼,還能訪問數據庫嗎?

> use test2
switched to db test2
> show dbs                                                                              #發現連數據庫都查看不了
2018-11-13T07:09:19.437+0000 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
    "code" : 13,
    "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:814:19
shellHelper@src/mongo/shell/utils.js:704:15
@(shellhelp2):1:1
> db.abc.find()                                          #test2數據庫的記錄也查看不了
Error: error: {
    "ok" : 0,
    "errmsg" : "not authorized on test2 to execute command { find: \"abc\", filter: {} }",
    "code" : 13,
    "codeName" : "Unauthorized"
}
> db.auth("test","test");                                    #開啟認證賬戶
1
> db.abc.find()                                          #成功
{ "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
> 

總結:mongo數據庫和別的數據庫認證過程是不一樣的,我們無需退出客戶端便可以自動切換用戶,來實現對不同數據庫的操作。mongo中,在哪個數據庫下創建的用戶,就在哪個數據庫下開啟認證,也就是說,在A數據庫創建的用戶user1,只能在數據庫A下面開啟認證,在B數據庫下面認證user1是不能成功的,在B數據庫下只能認證user2數據庫。數據庫賬戶是跟着數據庫走的。

 

現在我想刪除數據庫,

> use test2
switched to db test2
> show dbs
admin  0.000GB
local  0.000GB
test1  0.000GB
test2  0.000GB
> db.auth("test","test");
1
> db.abc.find()
{ "_id" : ObjectId("5bea76f00816d4c446c6c0d2"), "name" : "chaofeng", "id" : 1 }
{ "_id" : ObjectId("5bea7b4f6aeeebc0eb076f44"), "name" : "chen", "id" : 2 }
> db.dropDatabase();
{
    "ok" : 0,
    "errmsg" : "not authorized on test2 to execute command { dropDatabase: 1.0 }",
    "code" : 13,
    "codeName" : "Unauthorized"
}

發現是不能刪除數據庫的,仔細一想就知道test用戶只有對當前test2數據庫讀寫操作,但是沒有刪除權限。

我們再對test2數據庫創建一個用戶,使其擁有管理權限

> db
test2
> db.createUser(
... {
... user:"gl",
... pwd:"gl",
... roles:[{role:"dbOwner",db:"test2"}]
... }
... )
Successfully added user: {
    "user" : "gl",
    "roles" : [
        {
            "role" : "dbOwner",
            "db" : "test2"
        }
    ]
}> db.auth("gl","gl")
1
> db.dropDatabase()
{ "dropped" : "test2", "ok" : 1 }

現在我們創建的gl用戶擁有dbOwner角色,也就是對當前數據庫擁有最高管理權限,這個時候就可以刪除數據庫test2了。

 


免責聲明!

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



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