使用基于角色的访问控制(内置角色)限制数据库访问
您可以使用 中的基于角色的访问控制Amazon DocumentDB(与 MongoDB 兼容) (RBAC) 限制对用户可以对数据库执行的操作的访问。RBAC 的原理是向用户授予一个或多个角色。这些角色决定用户可以对指定数据库执行的操作。Amazon DocumentDB 目前支持数据库级别范围内的内置角色,例如,read
、readWrite
、readAnyDatabase
和 clusterAdmin
.
RBAC 的常见使用案例包括通过创建对集群中数据库具有只读访问权限的用户来强制执行最低权限,以及允许单个用户访问集群中给定数据库的多租户应用程序设计。
注意
所有在 2020 年 3 月 26 日之前创建的新用户都已被授予 dbAdminAnyDatabase
、readWriteAnyDatabase
和 clusterAdmin
角色。建议您重新评估所有现有用户并根据需要修改角色,以便为您的集群强制执行最低权限。
RBAC 概念
以下是与基于角色的访问控制相关的重要术语和概念。有关 Amazon DocumentDB 用户的更多信息,请参阅管理 Amazon DocumentDB 用户.
用户 — 可进行身份验证以访问数据库并执行操作的单个实体。
密码 — 用于对用户进行身份验证的密钥。
角色 — 授权用户对一个或多个数据库执行操作。
管理数据库 — 用户在其中存储并已得到授权的数据库。
数据库 (
db
) — 集群中包含用于存储文档的集合的命名空间。
以下命令创建名为 的用户。sample-user
.
db.createUser({user: "sample-user", pwd: "abc123", roles: [{role: "read", db: "sample-database"}]})
在此示例中:
user: "sample-user"
— 表示用户名。pwd: "abc123"
— 表示用户密码。role: "read", "db: "sample-database"
— 表示用户sample-user
将在sample-database
. 中具有读取权限。
以下示例显示您为用户 sample-user
指定 db.getUser(sample-user)
. 后的输出。在此示例中,用户 sample-user
驻留在 admin
数据库中,但具有 sample-database
. 数据库的读取角色。
在创建用户时,如果在指定角色时省略 db
字段,则 Amazon DocumentDB 会隐式地将该角色归属于发出连接的数据库。例如,如果您的连接是针对数据库 sample-database
发出的,并且您运行以下命令,则用户 sample-user
将在 admin
数据库中创建并具有对数据库 readWrite
的 sample-database
. 权限。
db.createUser({user: "sample-user", pwd: "abc123", roles: ["readWrite"]})
此操作的输出将类似于下文。
{
"user" : "sample-user",
"roles" : [
{
"db" : "sample-database",
"role" : "readWrite"
}
]
}
创建具有跨所有数据库范围的角色的用户(例如,readAnyDatabase
)需要在创建用户时处于 admin
数据库的上下文,或者在创建用户时明确指定角色的数据库。要针对 admin
数据库发出命令,可以使用命令 use admin
. 有关更多信息,请参阅 常见命令.
RBAC 入门
为帮助您掌握基于角色的访问控制,本部分将向您介绍通过为三个用户创建具有不同职能的角色来强制执行最低权限的示例方案。
user1
是一位新上任的经理,需要能够查看和访问集群中的所有数据库。user2
是一位新员工,只需访问同一集群中的一个数据库sample-database-1
user3
是现有员工,需要查看和访问同一集群中其以前无权访问的不同数据库sample-database-2
在这之后,user1
和 user2
都离开了公司,所以必须撤销他们的访问权限。
要创建用户和授予角色,进入集群用于进行身份验证的用户必须具有可以为 createUser
和 grantRole
. 执行操作的关联角色。例如,角色 admin
和 userAdminAnyDatabase
都可以授予执行上述功能的权限。有关每个角色的操作,请参阅内置角色.
注意
在 Amazon DocumentDB 中,所有用户和角色操作(例如,create
、get
、drop
、grant
、revoke
等等)都在 admin
数据库中隐式执行,无论您是否对 admin
数据库发出命令。
首先,要了解集群中的当前用户和角色,可以运行 show users
命令,如以下示例所示。您将看到两个用户,即集群的 serviceadmin
和主用户。这两个用户始终存在,无法将它们删除。有关更多信息,请参阅 管理 Amazon DocumentDB 用户.
show users
对于 user1
,使用以下命令创建具有对整个集群中所有数据库的读写访问权限的角色。
db.createUser({user: "user1", pwd: "abc123", roles: [{role: "readWriteAnyDatabase", db: "admin"}]})
此操作的输出将类似于下文。
{
"user" : "user1",
"roles" : [
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
}
]
}
对于 user2
,使用以下命令创建对数据库 sample-database-1
具有只读访问权限的角色。
db.createUser({user: "user2", pwd: "abc123", roles: [{role: "read", db: "sample-database-1"}]})
此操作的输出将类似于下文。
{
"user" : "user2",
"roles" : [
{
"role" : "read",
"db" : "sample-database-1"
}
]
}
要模拟 user3
是现有用户的方案,请先创建用户 user3
,然后将新角色分配给 user3
.
db.createUser({user: "user3", pwd: "abc123", roles: [{role: "readWrite", db: "sample-database-1"}]})
此操作的输出将类似于下文。
{
"user" : "user3",
"roles" : [
{
"role" : "readWrite",
"db" : "sample-database-1"
}
]
}
现在已创建用户 user3
,请将角色 user3
分配给 read
。sample-database-2
db.grantRolesToUser("user3", [{role: "read", db: "sample-database-2"}])
最后,user1
和 user2
都离开了公司,需要撤销他们对集群的访问权限。您可以通过删除用户来执行此操作,如下所示。
db.dropUser("user1")
db.dropUser("user2")
要确保所有用户都具有适当角色,可使用以下命令列出所有用户。
show users
此操作的输出将类似于下文。
{
"_id" : "serviceadmin",
"user" : "serviceadmin",
"db" : "admin",
"roles" : [
{
"db" : "admin",
"role" : "root"
}
]
}
{
"_id" : "master-user",
"user" : "master-user",
"db" : "admin",
"roles" : [
{
"db" : "admin",
"role" : "root"
}
]
}
{
"_id" : "user3",
"user" : "user3",
"db" : "admin",
"roles" : [
{
"db" : "sample-database-2",
"role" : "read"
},
{
"db" : "sample-database-1",
"role" : "readWrite"
}
]
}
以用户身份连接到 Amazon DocumentDB
在连接到 Amazon DocumentDB 集群时,需要在特定数据库的上下文中进行连接。默认情况下,如果未在连接字符串中指定数据库,则会在 test
数据库上下文中自动连接到集群。所有集合级别命令(如 insert
和 find
)都是针对 test
数据库中的集合发出的。
要查看您所在上下文或者 — 换句话说 — 对其发出命令的数据库,请在 mongo shell 中使用 db
命令,如下所示。
查询:
db
输出:
test
尽管默认连接可能位于 test
数据库的上下文中,但这并不一定意味着与连接关联的用户有权对 test
数据库执行操作。在上述示例方案中,如果您用于进行身份验证的用户 user3
是具有对 readWrite
数据库的 sample-database-1
权限的角色,则连接的默认上下文是 test
数据库。但是,如果您尝试将文档插入 test
数据库的集合中,您将收到 Authorization failure (授权失败) 错误消息。这是因为该用户未获得对该数据库执行该命令的授权,如下所示。
查询:
db
输出:
test
查询:
db.col.insert({x:1})
输出:
WriteCommandError({ "ok" : 0, "code" : 13, "errmsg" : "Authorization failure" })
如果您将连接上下文更改为 sample-database-1
数据库,则可以写入到集合中,因为该用户具有执行此操作的授权。
查询:
use sample-database-1
输出:
switched to db sample-database-1
查询:
db.col.insert({x:1})
输出:
WriteResult({ "nInserted" : 1})
使用特定用户对集群进行身份验证时,还可以在连接字符串中指定数据库。如果这样做,则用户在通过 use
数据库的身份验证后,不再需要执行 admin
命令。
以下连接字符串根据 admin
数据库对用户进行身份验证,但连接上下文则是 sample-database-1
数据库。
mongo "mongodb://user3:abc123@sample-cluster.node.us-east-1.docdb.amazonaws.com:27017/sample-database-2"
常见命令
本节提供在 中使用基于角色的访问控制的常用命令示例。Amazon DocumentDB. 您必须位于 admin
数据库的上下文中,才能创建和修改用户和角色。您可以使用 use admin
命令切换到 admin
数据库。
注意
对用户和角色的修改将隐式发生在 admin
数据库中。创建具有跨所有数据库范围的角色的用户(例如,readAnyDatabase
)需要在创建用户时处于 admin
数据库上下文(即 use admin
),或者在创建用户时明确指定角色的数据库(如本节的示例 2 所示)。
示例 1:创建对数据库 read
具有 foo
. 权限的角色的用户。
db.createUser({user: "readInFooBar", pwd: "abc123", roles: [{role: "read", db: "foo"}]})
此操作的输出将类似于下文。
{
"user" : "readInFooBar",
"roles" : [
{
"role" : "read",
"db" : "foo"
}
]
}
示例 2:创建具有所有数据库的读取访问权限的用户。
db.createUser({user: "readAllDBs", pwd: "abc123", roles: [{role: "readAnyDatabase", db: "admin"}]})
此操作的输出将类似于下文。
{
"user" : "readAllDBs",
"roles" : [
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
示例 3:向新数据库的现有用户授予 read
角色。
db.grantRolesToUser("readInFooBar", [{role: "read", db: "bar"}])
示例 4:更新用户的角色。
db.updateUser("readInFooBar", {roles: [{role: "read", db: "foo"}, {role: "read", db: "baz"}]})
示例 5:撤销用户对数据库的访问权限。
db.revokeRolesFromUser("readInFooBar", [{role: "read", db: "baz"}])
示例 6:描述内置角色。
db.getRole("read", {showPrivileges:true})
此操作的输出将类似于下文。
{
"role" : "read",
"db" : "sample-database-1",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ],
"privileges" : [
{
"resource" : {
"db" : "sample-database-1",
"collection" : ""
},
"actions" : [
"changeStream",
"collStats",
"dbStats",
"find",
"killCursors",
"listCollections",
"listIndexes"
]
}
],
"inheritedPrivileges" : [
{
"resource" : {
"db" : "sample-database-1",
"collection" : ""
},
"actions" : [
"changeStream",
"collStats",
"dbStats",
"find",
"killCursors",
"listCollections",
"listIndexes"
]
}
]
}
示例 7:从集群中删除用户。
db.dropUser("readInFooBar")
此操作的输出将类似于下文。
true
功能差异
在 Amazon DocumentDB 中,用户和角色定义存储在 admin
数据库中,而且根据 admin
数据库对用户进行身份验证。此功能与 MongoDB 社区版不同,但与 MongoDB Atlas 一致。
Amazon DocumentDB 还支持变更流,该功能提供按时间顺序排列的更改事件,这些事件在您的集群集合中发生。listChangeStreams
操作在集群级别(即跨所有数据库)应用,而 modifyChangeStreams
操作在数据库级别应用。
Limits
下表包含 中对内置角色的限制。Amazon DocumentDB. 请注意,目前 Amazon DocumentDB 不支持 RBAC 自定义角色。
描述 | 限制 |
---|---|
每个集群的用户数 | 1000 |
与用户关联的角色数 | 1000 |
内置角色
借助基于角色的访问控制,您可以创建一个用户并向其授予一个或多个角色,以确定该用户可以在数据库或集群中执行哪些操作。
以下是 中目前支持的内置角色的列表。Amazon DocumentDB.
注意
在 Amazon DocumentDB 4.0 中,ListCollection
和 ListDatabase
命令可以选择使用 authorizedCollections
和 authorizedDatabases
参数列出用户有权使用需要 listCollections
和 listDatabase
角色访问的集合和数据库。此外,用户现在还可以在不需要 KillCursor
角色的情况下终止自己的光标。
角色类型 | 角色名称 | 描述 | 操作 |
---|---|---|---|
数据库用户 | read | 授予用户对指定数据库的读取权限。 |
|
readWrite | 授予用户对指定数据库的读取和写入访问权限。 | 使用
| |
集群用户 | readAnyDatabase | 授予用户对集群中所有数据库的读取权限。 | 使用
|
readWriteAnyDatabase | 授予用户对集群中所有数据库的读写权限。 | 使用
| |
userAdminAnyDatabase | 授予用户为所有用户分配或修改对指定数据库的角色或权限的能力。 |
| |
dbAdminAnyDatabase | 授予用户对所有指定数据库执行数据库管理角色的能力。 | 使用
| |
Superuser | root | 向用户授予对以下所有角色组合的资源和操作的访问权限:readWriteAnyDatabase 、dbAdminAnyDatabase 、userAdminAnyDatabase 、clusterAdmin 、restore 和 backup 。 | 使用 |
数据库管理 | dbAdmin | 授予用户对指定数据库执行管理任务的能力。 |
|
dbOwner | 通过合并角色 dbAdmin 和 readWrite . 授予用户对指定数据库执行任何管理任务的能力。 | 使用 | |
集群管理 | clusterAdmin | 通过合并 clusterManager 、clusterMonitor 和 hostManager 角色授予用户最大的集群管理访问权限。 | 使用
|
clusterManager | 授予用户对指定集群执行管理和监控操作的能力。 |
| |
clusterMonitor | 授予用户对监控工具可具有只读访问权限的能力。 |
| |
hostManager | 授予用户监视和管理服务器的能力。 |
| |
备份管理 | backup | 授予用户备份数据所需的访问权限。 |
|
restore | 授予用户还原数据所需的访问权限。 |
|