接着上期,本期咱们来看看MongoDB 的用户权限部分,在权限这部分我们需要先说明一个部分的问题,建立一个账号的归属权,这里MongoDB 也是有系统库的,这里的对于用户有不同的含义,比如在admin里面建立的数据库用户和在普通应用库中建立的用户是有不同的,在admin 库建立的用户是可以具有全局的管理员的权限的,而在用户数据库中建立的用户,可以拥有这个库的最大的权限。这是需要说明的,而这些账号,建立在每个数据库的system.user 的集合中。

> show databases;
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

作为入门教学贴,我们先来熟悉一下MongoDB 的role 角色的部分,在给一个用户建立的时候,都需要对这个用户至少赋予一个角色来匹配相关的用户需要执行的功能。 主要 role分为如下几大类 

1  数据库用户的角色 

read 

readWrite 

2  数据库管理员账号 

dbAdmin

dbOwner 

userAdmin 

3  集群或复制集合账号 

clusterAdmin 

clusterManager 

clusterMonitor 

enableSharding 

hostManager 

4  备份和恢复角色 

backup 

restore 

5  非单一数据库账号类角色

readAnyDatabase

readWriteAnyDatabase 

userAdminAnyDatabase root

下面以问题的方式来对账号的问题进行一个学习 1  非单一的数据库账号类的角色和普通的角色之间的不同是什么 这里我们以 readAnyDatabase 和 read 做一个比较, 从下面的图中我们可以看到,如果是普通的只读账号,可以在任意的数据库中建立,而如果是建立非针对某一个数据库,而是针对所有的数据库都可以读取的账号,则必须将账号建立在 admin库中,否则建立的时候会报错,没有相关的role。

> db.createUser({
...   user: "test",
...   pwd: "test",
...   roles: [
...     { role: "read", db: "test" }
...   ]
... })
Successfully added user: {
 "user" : "test",
 "roles" : [
  {
   "role" : "read",
   "db" : "test"
  }
 ]
}
> db.createUser({
...   user: "testany",
...   pwd: "testany",
...   roles: [
...     { role: "readAnyDatabase", db: "test" }
...   ]
... })
uncaught exception: Error: couldn't add user: Could not find role: readAnyDatabase@test :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.createUser@src/mongo/shell/db.js:1362:11
@(shell):1:1
> db.createUser({
...   user: "testany",
...   pwd: "testany",
...   roles: [
...     { role: "readAnyDatabase", db: "admin" }
...   ]
... })
Successfully added user: {
 "user" : "testany",
 "roles" : [
  {
   "role" : "readAnyDatabase",
   "db" : "admin"
  }
 ]
}
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

问题 2 ,一次可以给一个账号赋予多个角色和多个数据库的权限吗

> use admin
switched to db admin
> 
> db.grantRolesToUser(
...   "test",
...   [
...     { role: "readAnyDatabase", db: "admin" },
...     { role: "clusterMonitor", db: "admin" },
...     { role: "read", db: "test" }
...   ]
... )
uncaught exception: Error: Could not find user "test" for db "admin" :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.grantRolesToUser@src/mongo/shell/db.js:1589:15
@(shell):1:1
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

一次性给已有的账号,进行赋予多个权限是可以的,但前提是你赋予的账号应该在你要赋值的数据库中已经存在此账号,上面的错误明显的问题在于在admin 数据库中并没有test 的账号

> use test
switched to db test
> 
> db.grantRolesToUser(
...   "test",
...   [
...     { role: "readAnyDatabase", db: "admin" },
...     { role: "clusterMonitor", db: "admin" },
...     { role: "read", db: "test" }
...   ]
... )
> use test
switched to db test
> 
> db.grantRolesToUser(
...   "test",
...   [
...     { role: "readAnyDatabase", db: "admin" },
...     { role: "clusterMonitor", db: "admin" },
...     { role: "read", db: "test" },
... { role: "backup", db: "test" },
...   ]
... )
uncaught exception: Error: Could not find role: backup@test :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.grantRolesToUser@src/mongo/shell/db.js:1589:15
@(shell):1:1
> 



> db.grantRolesToUser(
...   "test",
...   [
...     { role: "readAnyDatabase", db: "admin" },
...     { role: "clusterMonitor", db: "admin" },
...     { role: "read", db: "test" },
... { role: "backup", db: "test" },
...   ]
... )
uncaught exception: Error: Could not find role: backup@test :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.grantRolesToUser@src/mongo/shell/db.js:1589:15
@(shell):1:1
> 
> 
> 
> 
> db.grantRolesToUser(
...   "test",
...   [
...     { role: "readAnyDatabase", db: "admin" },
...     { role: "clusterMonitor", db: "admin" },
...     { role: "read", db: "test" },
... {role: "backup", db: "admin"}
...   ]
... )
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.

上图可以看到,对于添加用户的部分,需要注意

1 你所在用户的数据库可以赋予相关的role,如果没有则报错, 

2 一个Mongo实例里面,会存在同名的账号,但权限不同,寄生在不同的数据库内。参加下图。

> db.getUsers()
[
 {
  "_id" : "admin.test",
  "userId" : UUID("ebe01e6d-2102-4f2a-81a8-5d47c613e03c"),
  "user" : "test",
  "db" : "admin",
  "roles" : [
   {
    "role" : "readAnyDatabase",
    "db" : "admin"
   },
   {
    "role" : "read",
    "db" : "admin"
   },
   {
    "role" : "backup",
    "db" : "admin"
   },
   {
    "role" : "read",
    "db" : "test"
   },
   {
    "role" : "clusterMonitor",
    "db" : "admin"
   }
  ],
  "mechanisms" : [
   "SCRAM-SHA-1",
   "SCRAM-SHA-256"
  ]
 }
]
> use test
switched to db test
> db.getUsers()
[
 {
  "_id" : "test.test",
  "userId" : UUID("46a5ecc4-4c4b-44d7-9756-5b299a5c07be"),
  "user" : "test",
  "db" : "test",
  "roles" : [
   {
    "role" : "read",
    "db" : "test"
   },
   {
    "role" : "clusterMonitor",
    "db" : "admin"
   },
   {
    "role" : "readAnyDatabase",
    "db" : "admin"
   }
  ],
  "mechanisms" : [
   "SCRAM-SHA-1",
   "SCRAM-SHA-256"
  ]
 },
 {
  "_id" : "test.testany",
  "userId" : UUID("a52e5f1f-1be8-48a9-b12a-b733e781f9f5"),
  "user" : "testany",
  "db" : "test",
  "roles" : [
   {
    "role" : "readAnyDatabase",
    "db" : "admin"
   }
  ],
  "mechanisms" : [
   "SCRAM-SHA-1",
   "SCRAM-SHA-256"
  ]
 }
]
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.

问题:那么如果区分使用不同数据库里面的同名的数据库账号,想看到同名但不同数据库里面的账号的权限。可以使用 use admin 对system.user进行查询获得相关所有同名的数据库的权限列表。

> use admin
switched to db admin
> db.system.users.find({user: "test"})
{ "_id" : "admin.test", "userId" : UUID("ebe01e6d-2102-4f2a-81a8-5d47c613e03c"),
 "user" : "test", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, 
 "salt" : "++dxfXK4V/Hrwj193xubAA==", "storedKey" : "73SwUZIkLUFTC91OFV+GiUe5HWk=", 
 "serverKey" : "b6boRgk6GVLXkS7FWphP9amUeVg=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, 
 "salt" : "2vUagKnwzCSqRJ+jKC5B8qHE2MKK9Dpl5ZQI3Q==", "storedKey" : "JQyA4MXtbGDMsacOuDsu4k9DAkrZBEU3SBkg+wu97Ew=", "serverKey" : "NnTry6cA/FaWOi76FuRC5sW3EezcgR8AlPaaBf4mP6U=" } }, "roles" : [ { "role" : "readAnyDatabase", "db" : "admin" }, 
{ "role" : "read", "db" : "admin" }, 
{ "role" : "backup", "db" : "admin" }, 
{ "role" : "read", "db" : "test" }, 
{ "role" : "clusterMonitor", "db" : "admin" } ] }

{ "_id" : "test.test", "userId" : UUID("46a5ecc4-4c4b-44d7-9756-5b299a5c07be"),
 "user" : "test", "db" : "test", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, 
 "salt" : "WNUwx9cnVQS1A8Ex1kQ/fw==", "storedKey" : "LFXejbapLi3MGOTxh8MFMVv8ULo=",
 "serverKey" : "pN7e2N2YA4czXo91Ru5dcFF40Mo=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, 
 "salt" : "GhgY6nNbNjUrYF7EAqGfab1DgYN0j+wCBGBQ0g==", "storedKey" : "TvWDEJ2FVbRO1ULy4qySKGFmXGFghm57Rx11Kg0y6C4=", 
 "serverKey" : "bM/h/jSl/QxYSRbPNkm0w3otYnjN21mlJ3KLnnS9xJs=" } }, "roles" : [ { "role" : "read", "db" : "test" },
 { "role" : "clusterMonitor", "db" : "admin" }, { "role" : "readAnyDatabase", "db" : "admin" } ] }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

问题:回收部分用户的权限

回收权限时,需要先弄清楚眼红红有哪些权限,用下面的命令来获得你要回收的用户的权限列表

> db.system.users.find({user: "test"},{roles:1})
{ "_id" : "admin.test", "roles" : [ { "role" : "readAnyDatabase", "db" : "admin" }, { "role" : "read", "db" : "admin" }, { "role" : "backup", "db" : "admin" }, { "role" : "read", "db" : "test" }, { "role" : "clusterMonitor", "db" : "admin" } ] }
{ "_id" : "test.test", "roles" : [ { "role" : "read", "db" : "test" }, { "role" : "clusterMonitor", "db" : "admin" }, { "role" : "readAnyDatabase", "db" : "admin" } ] }
>
  • 1.
  • 2.
  • 3.
  • 4.

然后通过revokeRolesFromUser 来回收用户的权限,在用户所在的数据库中进行相关的操作。

> db.revokeRolesFromUser("test",["read","backup"])
> db.system.users.find({user: "test"},{roles:1})
{ "_id" : "admin.test", "roles" : [ { "role" : "read", "db" : "test" }, { "role" : "clusterMonitor", "db" : "admin" } ] }
{ "_id" : "test.test", "roles" : [ { "role" : "clusterMonitor", "db" : "admin" }, { "role" : "readAnyDatabase", "db" : "admin" } ] }
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

问题:怎么获得所有的数据库中的用户和相关的权限列表

> db.system.users.find({},{"user":1,"db":1,"roles":1}).pretty()
{
 "_id" : "test.test",
 "user" : "test",
 "db" : "test",
 "roles" : [
  {
   "role" : "clusterMonitor",
   "db" : "admin"
  },
  {
   "role" : "readAnyDatabase",
   "db" : "admin"
  }
 ]
}
{
 "_id" : "test.testany",
 "user" : "testany",
 "db" : "test",
 "roles" : [
  {
   "role" : "readAnyDatabase",
   "db" : "admin"
  }
 ]
}
{
 "_id" : "admin.test",
 "user" : "test",
 "db" : "admin",
 "roles" : [
  {
   "role" : "read",
   "db" : "test"
  },
  {
   "role" : "clusterMonitor",
   "db" : "admin"
  }
 ]
}
>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

问题:怎么获得所有的数据库中的用户和相关的权限列表 问题:统计当前用户中,具有clusterMonitor权限的用户

> db.system.users.find({"roles.role":"clusterMonitor"}).count()
2
  • 1.
  • 2.

对于用户的信息的统计,可以通过system.users来进行

问题: mongodb 中的root 和  userAdminAnyDatabase 权限是一个意思吗?

不是,ROOT 相当与一个全能者,从权限到数据的操作都可以进行,userAdminAnyDatabase 相当与一个管理权限者,但他不能直接操作数据,他可以给其他用户来赋予权限操作数据,除非他被显式赋予了相应的数据操作权限。。

Austindatabases 公众号,主要围绕数据库技术(PostgreSQL, MySQL, Mongodb, Redis, SqlServer,PolarDB, Oceanbase 等)和职业发展,国外数据库大会音译,国外大型IT信息类网站文章翻译,等,希望能和您共同发展。