MongoDB的用戶和角色權限簡介
默認情況下,
MongoDB實體啟動運行時是沒有啟用用戶訪問權限控制的,也就是說,在實體本機服務器上都可以隨意連接到實體進行各種操作,MongoDB不會對連接客戶端進行用戶驗證,為了強制開啟用戶訪問控制(用戶驗證),則需要在
MongoDB實體啟動時使用選項--auth或在指定啟動組態檔中添加auth=true,
- 啟用訪問控制:
MongoDB使用的是基于角色的訪問控制(Role-Based Access Control,RBAC)來管理用戶對實體的訪問,通過對用戶授予一個或多個角色來控制用戶訪問資料庫資源的權限和資料庫操作的權限,在對用戶分配角色之前,用戶無法訪問實體,- 角色:在
MongoDB中通過角色對用戶授予相應資料庫資源的操作權限,每個角色當中的權限可以顯示指定,也可以通過集成其他角色的權限,或者兩者都存在的權限,- 權限:權限由指定的資料庫(resource)以及允許在運行資源上進行的操作(action)組成,
- 資源(resource)包括:資料庫、集合、部分集合和集群;
- 操作(action)包括:對資源的增、刪、改、查(CRUD)操作,
在角色定義時可以包含一個或多個已存在的角色,新創建的角色會繼承包含的角色所有的權限,在同一個資料庫中,新創建角色可以繼承其他角色的權限,在
admin資料庫中創建的角色可以繼承在其它任意資料庫中的角色的權限,
角色權限的查看,可以通過如下的命令進行查看:
# 查詢所有角色權限(僅用戶自定義角色)
> db.runCommand({ rolesInfo: 1 })
# 查詢所有角色權限(包含內置角色)
> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })
# 查詢當前資料庫中的某角色的權限
> db.runCommand({ rolesInfo: "<rolename>" })
# 查詢其它資料庫中指定的角色權限
> db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }
# 查詢多個角色權限
> db.runCommand({
rolesInfo: [
"<rolename>", { role: "<rolename>", db: "<database>" },
...
]
})
示例:
查看所有內置角色:
> db.runCommand({rolesInfo:1, showBuiltinRoles:true})
{
"roles" : [
{
"role" : "__queryableBackup",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "__system",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "backup",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "clusterAdmin",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "clusterManager",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "clusterMonitor",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "dbAdmin",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "dbAdminAnyDatabase",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "dbOwner",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "enableSharding",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "hostManager",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "read",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "readAnyDatabase",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "readWrite",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "readWriteAnyDatabase",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "restore",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "root",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "userAdmin",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
},
{
"role" : "userAdminAnyDatabase",
"db" : "admin",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ]
}
],
"ok" : 1
}
常見的內置角色
- 資料庫用戶角色:
read、readWrite - 資料庫管理角色:
dbAdmin、dbOwner、userAdmin - 集群管理角色:
clusterAdmin、clusterManager、clusterMonitor - 所有資料庫用戶角色:
readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase - 備份恢復角色:
backup、restore - 超級用戶角色:
root - 內部角色:
system
?? 角色說明:
| 角色 | 權限描述 |
|---|---|
read |
可以讀取指定資料庫中任何資料, |
readWrite |
可以讀寫指定資料庫中任何資料,包括創建、重命名、洗掉集合 |
readAnyDatabase |
可以讀取所有資料庫中任何資料(除了資料庫config和local之外) |
readWriteAnyDatabase |
可以讀寫所有資料庫中任何資料(除了資料庫config和local之外) |
userAdminAnyDatabase |
可以在指定資料庫創建和修改用戶(除了資料庫config和local之外) |
dbAdminAnyDatabase |
可以讀取任何資料庫以及對資料庫進行清理、修改、壓縮、獲取統計資訊、執行檢查等操作(除了資料庫config和local之外) |
dbAdmin |
可以讀取指定資料庫以及對資料庫進行清理、修改、壓縮、獲取統計資訊、執行檢查等操作 |
userAdmin |
可以在指定資料庫創建和修改用戶 |
clusterAdmin |
可以對整個集群或資料庫系統進行管理操作 |
backup |
備份MongoDB資料最小的權限 |
restore |
從備份檔案中還原恢復MongoDB資料(除了system.profile集合)的權限 |
root |
超級賬戶,超級權限 |
單實體環境
創建用戶
?? 創建用戶格式如下:
db.createUser({
user:"<name>",
pwd:"<password>",
customData:{<any Object Data},
roles:[
{role:"<role>",db:"database"},
...
]
})
備注:
1)user:新建用戶名
2)pwd:新建用戶密碼
3)customData:存放一些用戶相關的自定義資料,可忽略
4)roles:資料型別,配置用戶的權限
示例:創建一個管理員賬戶
# mongo --host=10.10.10.11 --port=27017
> show dbs;
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.000GB
>
> use admin
switched to db admin
>
> db.createUser({"user":"root","pwd":"123456","roles":[{"role":"root","db":"admin"}]});
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
?? 查看用戶
# 方法一
> use admin;
switched to db admin
>
> show users;
{
"_id" : "admin.root",
"userId" : UUID("d7280144-2886-45eb-95f3-1965be4eb7fe"),
"user" : "root",
"db" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
],
"mechanisms" : [
"SCRAM-SHA-1",
"SCRAM-SHA-256"
]
}
# 方法二
> use admin;
switched to db admin
>
> show tables;
system.users
system.version
>
> db.system.users.find()
{ "_id" : "admin.root", "userId" : UUID("d7280144-2886-45eb-95f3-1965be4eb7fe"), "user" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "u2nQBHuC2P367Qo5mLhcRw==", "storedKey" : "0ccLsqhpWUyCdAoQKZQNNHwvj9g=", "serverKey" : "9Qxfsw+GCQMwUuyz9AlKRAX6zx0=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "rxajlRAv8zteEMm6r2Wx8GFY1ShBeLjHUqJ7iA==", "storedKey" : "T9z/0GJ21cxJ4CvnNL+PBGkTYwdPu9YxmRo1CQ2tGp0=", "serverKey" : "UBVuzHOxfKADUdpxIhRBab2HwPdLhNL2yUZzyTXFRt0=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ]
服務端開啟認證
?? 修改組態檔
# vim /usr/local/mongodb/conf/mongodb.conf
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/log/mongodb.log
bind_ip=0.0.0.0
port=27017
logappend=1
fork=1
auth=true #開啟認證
?? 重啟服務
# ps -ef |grep mongod
root 6991 1 0 19:46 ? 00:00:10 mongod -f /usr/local/mongodb/conf/mongodb.conf
root 7438 6395 0 20:14 pts/1 00:00:00 grep --color=auto mongod
# kill -2 6991
#
# mongod -f /usr/local/mongodb/conf/mongodb.conf
?? 登陸測驗
# mongo --host=10.10.10.11 --port=27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("cb337048-a9c8-45ae-99aa-b0cb8cc7a163") }
MongoDB server version: 4.4.1
> show dbs #查看
>
> use admin #切換到admin庫
switched to db admin
> db.auth("root","123456") #進行認證
1
> show dbs;
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.000GB
?? 添加一個普通用戶
創建普通用戶可以在沒有開啟認證的時候添加,也可以在開啟認證之后添加,但開啟認證之后,必須使用有操作
admin庫的用戶登錄認證后才能操作,底層是將用戶資訊保存在了admin資料庫的集合system.users中,
# 創建(切換)將來要操作的資料庫articledb
> use articledb
switched to db articledb
>
> db.createUser({user:"user1",pwd:"1234",roles:[{role:"readWrite",db:"articledb"}]})
Successfully added user: {
"user" : "user1",
"roles" : [
{
"role" : "readWrite",
"db" : "articledb"
}
]
}
# 測驗是否可用
> db.auth("user1","1234")
1
客戶端登錄認證
?? 方法1
先連接,在認證
# mongo --host 10.10.10.11 --port 27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("4efbbc03-31b7-45ff-8b3a-5ce6f76ff1ca") }
MongoDB server version: 4.4.1
> use admin
switched to db admin
> db.auth("root","123456")
1
> show dbs
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.000GB
?? 方法2
連接時進行認證
# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?authSource=admin&compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("0848b5d0-fb56-40eb-9b37-542682fd6ada") }
MongoDB server version: 4.4.1
......
>
> show dbs
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.000GB
引數說明:
--host:連接的主機地址--port:連接的埠--authenticationDatabase:指定連接到哪個庫,當登錄是指定用戶密碼時,必須指定對應的資料庫!-u:用戶名-p:密碼
副本集環境
對于搭建好的
mongodb副本集,為了安全,啟動安全認證,使用賬戶密碼登錄,對副本集執行訪問控制需要配置兩個方面:
1)副本集和共享集群的各個節點成員之間使用內部身份驗證,可以使用秘鑰檔案或
x.509證書,秘鑰檔案比較簡單,2)使用客戶端連接到
mongodb集群時,可開啟訪問授權,對于集群外部的訪問,如通過可視化客戶端、或者通過代碼連接的時候,需要開啟授權,
添加管理賬戶
在主節點添加管理賬戶,副本集會自動同步,
myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> db.createUser({user:"root",pwd:"123456",roles:[{role:"root",db:"admin"}]})
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
備注:
該步驟也可以在開啟認證之后,但需要通過localhost登錄才允許添加用戶,用戶資料也會自動同步到副本集,后續再創建其他用戶,都已使用該超管用戶創建,
創建副本集認證的key檔案
?? 生成一個key檔案到當前檔案夾中,
可以使用任何方法生成秘鑰檔案,例如,一下使用openssl生成密碼檔案,然后使用chmod來更改檔案權限,僅為檔案所有這提供讀取權限,
# openssl rand -base64 90 -out ./mongo.keyfile
# chmod 400 ./mongo.keyfile
# ll mongo.keyfile
-r--------. 1 root root 122 Nov 17 16:27 mongo.keyfile
備注:
所有副本集節點都必須使用同一份keyfile,一般在一臺機器上生成,然后拷貝到其他機器上,且必須有讀的權限,否則將來會報錯:permissions on /mongodb/replica_sets/myrs_27017/mongo.keyfile are too open
一般情況下和組態檔放置在一起,方便查找,這里都copy到各個節點的組態檔目錄
# cp mongo.keyfile /data/replica_sets/myrs_27017/
# cp mongo.keyfile /data/replica_sets/myrs_27018/
# cp mongo.keyfile /data/replica_sets/myrs_27019/
修改組態檔指定keyfile
分別編輯幾個服務的
mongod.conf檔案,添加相關內容
# vim /data/replica_sets/myrs_27017/mongod.conf
security:
#keyfile鑒權檔案
keyFile: /data/replica_sets/myrs_27017/mongo.keyfile
#開啟認證方式運行
authorization: enabled
# vim /data/replica_sets/myrs_27018/mongod.conf
security:
#keyfile鑒權檔案
keyFile: /data/replica_sets/myrs_27018/mongo.keyfile
#開啟認證方式運行
authorization: enabled
# vim /data/replica_sets/myrs_27019/mongod.conf
security:
#keyfile鑒權檔案
keyFile: /data/replica_sets/myrs_27019/mongo.keyfile
#開啟認證方式運行
authorization: enabled
重啟副本集
如果副本集是開啟狀態,則先分別關閉副本集中的每個
mongod,從次節點開始,直到副本集的所有成員都離線,包括任何仲裁者,主節點必須是最后一個成員關閉,以避免潛在的回滾,
# ps -ef |grep mongod
root 2649 1 1 11:20 ? 00:04:44 mongod -f /data/replica_sets/myrs_27017/mongod.conf
root 2728 1 1 11:20 ? 00:05:21 mongod -f /data/replica_sets/myrs_27018/mongod.conf
root 4534 1 0 14:13 ? 00:01:07 mongod -f /data/replica_sets/myrs_27019/mongod.conf
# kill -2 2649 4534 2728
分別啟動副本集
# mongod -f /data/replica_sets/myrs_27017/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 6287
child process started successfully, parent exiting
#
# mongod -f /data/replica_sets/myrs_27018/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 6365
child process started successfully, parent exiting
#
# mongod -f /data/replica_sets/myrs_27019/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 6456
child process started successfully, parent exiting
查看行程情況
# ps -ef |grep mongo
root 6287 1 3 16:40 ? 00:00:02 mongod -f /data/replica_sets/myrs_27017/mongod.conf
root 6365 1 3 16:41 ? 00:00:02 mongod -f /data/replica_sets/myrs_27018/mongod.conf
root 6456 1 2 16:41 ? 00:00:01 mongod -f /data/replica_sets/myrs_27019/mongod.conf
連接測驗
連接主節點測驗
?? 先連接,再認證
# mongo --host 10.10.10.11 --port 27017
MongoDB shell version v4.4.1
connecting to: mongodb://10.10.10.11:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("e1218d07-5094-468d-bdfe-f1d3e3815281") }
MongoDB server version: 4.4.1
myrs:PRIMARY> show dbs
myrs:PRIMARY> db.auth("root","123456")
1
myrs:PRIMARY> show dbs
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
?? 連接時進行認證
# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
---
myrs:PRIMARY> show dbs
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
連接副本節點測驗
# mongo --host 10.10.10.11 --port 27018 --authenticationDatabase admin -u root -p 123456
myrs:SECONDARY> show dbs #查看資料庫,這里不能查看是因為默認副本節點不能查詢資料,需要開啟查詢權限
uncaught exception: Error: listDatabases failed:{
"topologyVersion" : {
"processId" : ObjectId("5fb38ca9ae9c791f8008eb9a"),
"counter" : NumberLong(4)
},
"operationTime" : Timestamp(1605603187, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1605603187, 1),
"signature" : {
"hash" : BinData(0,"hCt+wCrLo2uwZucZsLN0id+Rnh0="),
"keyId" : NumberLong("6893051287466672133")
}
}
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12
shellHelper.show@src/mongo/shell/utils.js:937:13
shellHelper@src/mongo/shell/utils.js:819:15
@(shellhelp2):1:1
myrs:SECONDARY>
myrs:SECONDARY> rs.secondaryOk() #開啟副本集讀取權限
myrs:SECONDARY>
myrs:SECONDARY> show dbs #再次查看
admin 0.000GB
collectest 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
添加普通用戶
?? 添加普通用戶對指定庫有讀寫權限
//連接主節點
# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase admin -u root -p 123456
myrs:PRIMARY> use collectest #切換到collectest庫
switched to db collectest
myrs:PRIMARY>
myrs:PRIMARY> db.createUser({user:"u_test",pwd:"123",roles:[{role:"readWrite", db:"collectest"}]}) #創建用戶u_test對collectest庫有讀寫權限
Successfully added user: {
"user" : "u_test",
"roles" : [
{
"role" : "readWrite",
"db" : "collectest"
}
]
}
myrs:PRIMARY>
?? 使用普通用戶登錄并查詢資料
# mongo --host 10.10.10.11 --port 27017 --authenticationDatabase collectest -u u_test -p 123
...
myrs:PRIMARY>
myrs:PRIMARY> show dbs
collectest 0.000GB
myrs:PRIMARY>
myrs:PRIMARY> use collectest
switched to db collectest
myrs:PRIMARY>
myrs:PRIMARY> show collections
collectest
myrs:PRIMARY>
myrs:PRIMARY> db.collectest.find()
{ "_id" : ObjectId("5faa3432f6e79c62c00e4d72"), "name" : "張三", "sex" : "男", "age" : 22, "userid" : 1001, "createdatetime" : ISODate("2020-11-10T06:33:22.459Z") }
{ "_id" : ObjectId("5facec10cca53c48154d261c"), "name" : "小白", "sex" : "女", "age" : 20, "userid" : 1002, "createdatetime" : ISODate("2020-11-12T08:02:24.915Z") }
{ "_id" : ObjectId("5facf32dfb5fe16aaf699d7d"), "name" : "小嘿", "sex" : "女", "age" : 21, "userid" : 1002, "createdatetime" : ISODate("2020-11-12T08:32:45.919Z") }
myrs:PRIMARY>
#查詢一個普通用戶沒有權限的庫,則會提示回應警告,并無法查看成功,
myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/223903.html
標籤:NoSQL
上一篇:解決Mac bigsur 中 Can‘t use Subversion command line client:svn
