天天看點

Mongodb學習筆記--使用者和權限

# Mongodb 使用者和身份驗證

mongodb預設是沒有使用者名和密碼的,隻要連接配接成功就可以操作,但是如果要将mongodb作為項目中間件上線的話,肯定不希望任何人都可以通路,為了保證資料安全,mongodb提供了addUser方法來添加使用者。

該方法包含三個參數:

~~~

user: 使用者名    

pwd: 密碼  

roles: 集合類型。使用者所擁有的角色

添加使用者:db.createUser({user:"使用者名", pwd:"密碼", roles:[{role:"角色", db:"資料庫"}]})  

删除使用者:db.dropUser("使用者名")

~~~

##Mongodb使用者分為兩類:超級使用者和資料庫使用者

資料庫的使用者都存放在admin資料庫下:

```shell script

db.system.users

```

### 超級使用者

mongodb的超級使用者存儲在admin資料庫中,該資料庫中的使用者可以對所有的資料庫進行任意操作,擁有最大的權限。mongodb剛安裝時,admin資料庫是空的。

### 資料庫使用者

資料庫使用者是存放在單個資料庫中的,隻能通路對應的資料庫。

### 使用者和權限的特性

* 資料庫是由超級使用者建立的,一個資料庫可以包含多個使用者,一個使用者隻能在一個資料庫下。不同的資料庫下使用者名可以相同

* 如果在admin資料庫中不存在使用者,即使在mongodb啟動時添加了-auth參數,此時不進行任何認證還是可以作任何操作

* 在admin資料庫建立的使用者具有超級權限,可以對系統内的任何資料庫資料對象進行操作

* 資料庫test下的使用者test_user1不能通路其他資料庫如local、test2,但是可以通路同一資料庫下其他使用者如test_user2建立的資料

* 不同資料庫下的同一使用者名使用者,在一個資料庫登陸後,不能再另一個資料庫登入。如test1、test2資料庫下都有使用者test_user使用者,那麼test_user使用者再test1登入後,不能再test2登入。

### 驗證以上特性

打開之前配置的mongodb叢集,連入master:27017端口。

```shell script

[root@moggledb ~]# mongo --host 192.168.226.130 --port 27017

...

rs0:PRIMARY>

```

此時admin資料庫中仍沒有任何使用者,是以可以再任意資料庫下通路其他資料庫。

```shell script

rs0:PRIMARY> show dbs

local  1.078GB

test   0.078GB

rs0:PRIMARY> use local

switched to db local

rs0:PRIMARY> use test

switched to db test

```

從local資料庫下通路test資料庫,切換成功。  

檢視admin資料庫下的users表。  

```shell script

rs0:PRIMARY> db.system.users.find()

rs0:PRIMARY>  

```

此時db.system.users為空,是以是超級管理者權限,可以通路任意資料庫。

+ 驗證:資料庫是由超級使用者建立的,一個資料庫可以包含多個使用者,一個使用者隻能在一個資料庫下。不同的資料庫下使用者名可以相同

```shell script

rs0:PRIMARY> use test1

rs0:PRIMARY> db.createUser({user:"admin", pwd:"123465", roles:[{role:"readWrite", db:"test1"}]})

Successfully added user: {

       "user" : "admin",

       "roles" : [

               {

                       "role" : "readWrite",

                       "db" : "test1"

               }

       ]

}

```

使用者建立成功後,使用者資訊會存放在admin資料庫下的system.users中。再admin下再建立一個超級使用者

```shell script

rs0:PRIMARY> use admin

switched to db admin

rs0:PRIMARY> db.system.users.find()

{ "_id" : "test1.admin", "user" : "admin", "db" : "test1", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "2gOLsZlScfAloQ9rdiL3tA==", "storedKey" : "JWG+rgHy+jbXG

1EDxYDXgfd17Jw=", "serverKey" : "cWCH2UwJ3f4Tg86smNZtenC0EUs=" } }, "roles" : [ { "role" : "readWrite", "db" : "test1" } ] }

rs0:PRIMARY> db.createUser({user:"root", pwd:"root", roles:[{role:"userAdminAnyDatabase", db:"admin"}]})

Successfully added user: {

       "user" : "root",

       "roles" : [

               {

                       "role" : "userAdminAnyDatabase",

                       "db" : "admin"

               }

       ]

}

rs0:PRIMARY> db.system.users.find()

{ "_id" : "test1.admin", "user" : "admin", "db" : "test1", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "2gOLsZlScfAloQ9rdiL3tA==", "storedKey" : "JWG+rgHy+jbXG

1EDxYDXgfd17Jw=", "serverKey" : "cWCH2UwJ3f4Tg86smNZtenC0EUs=" } }, "roles" : [ { "role" : "readWrite", "db" : "test1" } ] }

{ "_id" : "admin.root", "user

" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "PJPZSCq9YqY96QOWgVPnRQ==", "storedKey" : "VAO+Now5XIzkmew

kRFr3TIKU6J0=", "serverKey" : "9V2ArT9CWsunH8TCk/lY1oCAUzk=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }

```

此時我們test1資料庫有了使用者admin,然後再test2下建立相同使用者admin

```shell script

rs0:PRIMARY> use test2

switched to db test2

rs0:PRIMARY> db.createUser({user:"admin", pwd:"123456", roles:[{role:"readWrite", db:"test2"}]})

Successfully added user: {

       "user" : "admin",

       "roles" : [

               {

                       "role" : "readWrite",

                       "db" : "test2"

               }

       ]

}

rs0:PRIMARY> db.createUser({user:"test2",pwd:"test2",roles:[{role:"read", db:"test2"}]})

Successfully added user: {

       "user" : "test2",

       "roles" : [

               {

                       "role" : "read",

                       "db" : "test2"

               }

       ]

}

rs0:PRIMARY> db.getUsers()

[

       {

               "_id" : "test2.admin",

               "user" : "admin",

               "db" : "test2",

               "roles" : [

                       {

                               "role" : "readWrite",

                               "db" : "test2"

                       }

               ]

       },

       {

               "_id" : "test2.test2",

               "user" : "test2",

               "db" : "test2",

               "roles" : [

                       {

                               "role" : "read",

                               "db" : "test2"

                       }

               ]

       }

]

rs0:PRIMARY>

```

可以看到,不同資料庫下可以有相同的使用者名。同一個資料庫下可以有多個使用者。

* 在admin資料庫建立的使用者具有超級權限,可以對系統内的任何資料庫資料對象進行操作  

退出primary節點,停掉叢集節點。先停掉備份節點,在停主節點。

```shell script

rs0:PRIMARY> exit

bye

[root@moggledb ~]# mongod --shutdown --dbpath /data/node3

killing process with pid: 2768

[root@moggledb ~]# mongod --shutdown --dbpath /data/node2

killing process with pid: 2679

[root@moggledb ~]# mongod --shutdown --dbpath /data/node1

killing process with pid: 2595

[root@moggledb ~]# ps -ef |grep mongod

root       8347   2571  0 22:10 pts/0    00:00:00 grep mongod

[root@moggledb ~]#

```

在primary節點上生成keyfile檔案

```shell script

[root@moggledb ~]# openssl rand -base64 666 > /data/node1/keyfile

[root@moggledb ~]# chmod 600 /data/node1/keyfile

```

将keyfile複制到其他節點上,并修改權限為600

```shell script

[root@moggledb ~]# openssl rand -base64 666 > /data/node1/keyfile

[root@moggledb ~]# chmod 600 /data/node1/keyfile

[root@moggledb ~]# cp /data/node1/keyfile /data/node2/

[root@moggledb ~]# cp /data/node1/keyfile /data/node3/

[root@moggledb ~]# chmod 600 /data/node2/keyfile

[root@moggledb ~]# chmod 600 /data/node3/keyfile

```

修改primary節點啟動配置檔案:

```properties

auth=true

oplogSize=100

keyFile=/data/node1/keyfile

```

修改secondary節點配置檔案:

```properties

oplogSize=100

keyFile=/data/node2/keyfile

```

啟動副本集,先啟動主節點:

```shell script

[root@moggledb ~]# mongod -f /data/node1/mongodb-node1.conf

about to fork child process, waiting until server is ready for connections.

forked process: 8368

child process started successfully, parent exiting

[root@moggledb ~]# mongod -f /data/node2/mongodb-node2.conf

about to fork child process, waiting until server is ready for connections.

forked process: 8452

child process started successfully, parent exiting

[root@moggledb ~]# mongod -f /data/node3/mongodb-node3.conf

about to fork child process, waiting until server is ready for connections.

forked process: 8535

child process started successfully, parent exiting

[root@moggledb ~]# ps -ef |grep mongod

root       8368      1  1 22:22 ?        00:00:00 mongod -f /data/node1/mongodb-node1.conf

root       8452      1  1 22:22 ?        00:00:00 mongod -f /data/node2/mongodb-node2.conf

root       8535      1  2 22:22 ?        00:00:00 mongod -f /data/node3/mongodb-node3.conf

root       8598   2571  0 22:23 pts/0    00:00:00 grep mongod

[root@moggledb ~]#

```

連接配接主節點

```shell script

[root@moggledb node1]# mongo --username root --password root admin --host 192.168.226.130 --port 27017

MongoDB shell version: 3.0.6

connecting to: 192.168.226.130:27017/admin

rs0:PRIMARY> show dbs

admin  0.078GB

local  1.078GB

test   0.078GB

test1  0.078GB

rs0:PRIMARY>

```

root使用者是超級使用者,可以檢視所有的資料庫。但是如果要操作某一個資料庫内的資料的話,還是需要使用資料的使用者,root使用者無權限。

```shell script

rs0:PRIMARY> db.system.users.find()

{ "_id" : "test1.admin", "user" : "admin", "db" : "test1", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "2gOLsZlScfAloQ9rdiL3tA==", "storedKey" : "JWG+rgHy+jbXG1EDxYDXgfd17Jw=", "serverKey" : "cWCH2UwJ3f4Tg86smNZtenC0EUs=" } }, "roles" : [ { "role" : "readWrite", "db" : "test1" } ] }

{ "_id" : "admin.root", "user" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "PJPZSCq9YqY96QOWgVPnRQ==", "storedKey" : "VAO+Now5XIzkmewkRFr3TIKU6J0=", "serverKey" : "9V2ArT9CWsunH8TCk/lY1oCAUzk=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }

{ "_id" : "test2.admin", "user" : "admin", "db" : "test2", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "bpf9kX28M/qcjItzYRCh0A==", "storedKey" : "ptn1v5z70h0u2HYdh2SgBt8lI+s=", "serverKey" : "Wh3m8g2olZhoP5Xho2p6HS+CJrs=" } }, "roles" : [ { "role" : "readWrite", "db" : "test2" } ] }

{ "_id" : "test2.test2", "user" : "test2", "db" : "test2", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "8XmR1dpRQc4Tpb0JLzEsZw==", "storedKey" : "npUCRpSPlI5xAmEkbeKkJU5BC9U=", "serverKey" : "ZzbabAQR5VblYw+Lx4yE82Y33mQ=" } }, "roles" : [ { "role" : "read", "db" : "test2" } ] }

rs0:PRIMARY> use test1

switched to db test1

rs0:PRIMARY> show collections

2020-05-06T23:55:18.738-0700 E QUERY    Error: listCollections failed: {

       "ok" : 0,

       "errmsg" : "not authorized on test1 to execute command { listCollections: 1.0 }",

       "code" : 13

}

   at Error (<anonymous>)

   at DB._getCollectionInfosCommand (src/mongo/shell/db.js:646:15)

   at DB.getCollectionInfos (src/mongo/shell/db.js:658:20)

   at DB.getCollectionNames (src/mongo/shell/db.js:669:17)

   at shellHelper.show (src/mongo/shell/utils.js:625:12)

   at shellHelper (src/mongo/shell/utils.js:524:36)

   at (shellhelp2):1:1 at src/mongo/shell/db.js:646

rs0:PRIMARY>

```

使用test1資料庫的admin使用者認證:

```shell script

rs0:PRIMARY> db.auth("admin","123465")

1

rs0:PRIMARY> show collections

coll

system.indexes

```

注意我在上面設定test1資料庫密碼時,寫錯了,寫成了123465,是以這裡認證時密碼也要是123465。

* 使用test2資料庫的admin使用者插入一條資料,用test2使用者去檢視資料

```shell script

rs0:PRIMARY> use test2

switched to db test2

rs0:PRIMARY> db.auth("admin","123456")

rs0:PRIMARY> db.coll.insert({"name":"java"})

WriteResult({ "nInserted" : 1 })

rs0:PRIMARY> db.auth("test2","test2")

1

rs0:PRIMARY> db.coll.find()

{ "_id" : ObjectId("5eb3b5bd7e5f031e229d4cf2"), "name" : "java" }

rs0:PRIMARY> db.coll.insert({"text":"hello mongodb"})

WriteResult({

       "writeError" : {

               "code" : 13,

               "errmsg" : "not authorized on test2 to execute command { insert: \"coll\", documents: [ { _id: ObjectId('5eb3b63a7e5f031e229d4cf3'), text: \"hello mongodb\" } ], ordered:

true }"

       }

})