使用基于角色的访问控制进行数据库访问 - Amazon DocumentDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用基于角色的访问控制进行数据库访问

您可以使用 Amazon DocumentDB(与 MongoDB 兼容)中的基于角色的访问控制(RBAC)限制用户可以对数据库执行的操作的访问权限。RBAC 的原理是向用户授予一个或多个角色。这些角色决定了用户可以对数据库资源执行的操作。Amazon DocumentDB 目前既支持限定在数据库级别的内置角色(例如readreadWritereadAnyDatabaseclusterAdmin),也支持限定为特定操作的用户定义角色和精细资源(例如基于您的要求的集合)。

RBAC 的常见使用案例包括通过创建对集群中数据库具有只读访问权限的用户来强制执行最低权限,以及允许单个用户访问集群中给定数据库的多租户应用程序设计。

注意

所有在 2020 年 3 月 26 日之前创建的新用户都已被授予 dbAdminAnyDatabasereadWriteAnyDatabaseclusterAdmin 角色。建议您重新评估所有现有用户并根据需要修改角色,以便为您的集群强制执行最低权限。

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 中具有读取权限。

代码示例显示 createuser 命令,指示用户名、密码和权限。

以下示例显示您为用户 sample-user 指定 db.getUser(sample-user) 后的输出。在此示例中,用户 sample-user 驻留在 admin 数据库中,但具有 sample-database 数据库的读取角色。

代码输出示例显示 createUser 命令的结果,该命令定义了新用户 ID、分配给新用户的管理数据库以及应用于此用户的角色权限。

在创建用户时,如果在指定角色时省略 db 字段,则 Amazon DocumentDB 会隐式地将该角色归属于发出连接的数据库。例如,如果您的连接是针对数据库 sample-database 发出的,并且您运行以下命令,则用户 sample-user 将在 admin 数据库中创建并具有对数据库 sample-databasereadWrite 权限。

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

在这之后,user1user2 都离开了公司,所以必须撤销他们的访问权限。

要创建用户和授予角色,进入集群用于进行身份验证的用户必须具有可以为 createUsergrantRole 执行操作的关联角色。例如,角色 adminuserAdminAnyDatabase 都可以授予执行上述功能的权限。有关每个角色的操作,请参阅使用基于角色的访问控制进行数据库访问

注意

在 Amazon DocumentDB 中,所有用户和角色操作(例如,creategetdropgrantrevoke 等等)都在 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 分配可对 sample-database-2 进行 read 的角色。

db.grantRolesToUser("user3", [{role: "read", db: "sample-database-2"}])

最后,user1user2 都离开了公司,需要撤销他们对集群的访问权限。您可以通过删除用户来执行此操作,如下所示。

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" } ] }

RBAC 用户定义角色入门

为了帮助您开始使用用户定义的角色,本节将带您了解通过为具有不同工作功能的三个用户创建角色来强制执行最低权限的示例场景。

在本例中,以下条件适用:

  • user1 是一位新上任的经理,需要能够查看和访问集群中的所有数据库。

  • user2 是一位新员工,只需要对同一集群中的一个数据库 sample-database-1 执行“查找”操作。

  • user3 是现有员工,需要查看和访问不同数据库 sample-database-2 中的特定集合 col2,而他们以前在同一集群中无法访问该集合。

  • 对于 user1,使用以下命令创建具有对整个集群中所有数据库的读写访问权限的角色。

db.createUser( { user: "user1", pwd: "abc123", roles: [{role: "readWriteAnyDatabase", db: "admin"}] } )

此操作的输出将类似于下文。

{ "user":"user1", "roles":[ { "role":"readWriteAnyDatabase", "db":"admin" } ] }

对于 user2,使用以下命令创建一个对数据库 sample-database-1 中所有集合具有“查找”权限的角色。请注意,此角色将确保任何关联用户只能运行查找查询。

db.createRole( { role: "findRole", privileges: [ { resource: {db: "sample-database-1", collection: ""}, actions: ["find"] }], roles: [] } )

此操作的输出将类似于下文。

{ "role":"findRole", "privileges":[ { "resource":{ "db":"sample-database-1", "collection":"" }, "actions":[ "find" ] } ], "roles":[ ] }

接下来,创建用户(user2)并将最近创建的角色 findRole 附加到该用户。

db.createUser( { user: "user2", pwd: "abc123", roles: [] }) db.grantRolesToUser("user2",["findRole"])

为了模拟 user3 是现有用户的场景,首先创建用户 user3,然后创建一个名为 collectionRole 的新角色,我们将在下一步中分配到 user3

现在,您可以分配新角色到 user3。此新角色将允许user3插入、更新、删除和查找sample-database-2中一个特定集合 col2 的访问权限。

db.createUser( { user: "user3", pwd: "abc123", roles: [] }) db.createRole( { role: "collectionRole", privileges: [ { resource: {db: "sample-database-2", collection: "col2"}, actions: ["find", "update", "insert", "remove"] }], roles: [] } )

此操作的输出将类似于下文。

{ "role":"collectionRole", "privileges":[ { "resource":{ "db":"sample-database-2", "collection":"col2" }, "actions":[ "find", "update", "insert", "remove" ] } ], "roles":[ ] }

现在已创建了用户 user3,你可以位角色 collectionFind 分配 user3

db.grantRolesToUser("user3",["collectionRole"])

最后,user1user2 都离开了公司,需要撤销他们对集群的访问权限。您可以通过删除用户来执行此操作,如下所示。

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":"admin", "role":"collectionRole" } ] }

以用户身份连接到 Amazon DocumentDB

在连接到 Amazon DocumentDB 集群时,需要在特定数据库的上下文中进行连接。默认情况下,如果未在连接字符串中指定数据库,则会在 test 数据库上下文中自动连接到集群。所有集合级别命令(如 insertfind)都是针对 test 数据库中的集合发出的。

要查看您所在上下文或者换句话说,对其发出命令的数据库,请在 mongo shell 中使用 db 命令,如下所示。

查询:

db

输出:

test

尽管默认连接可能位于 test 数据库的上下文中,但这并不一定意味着与连接关联的用户有权对 test 数据库执行操作。在上述示例方案中,如果您用于进行身份验证的用户 user3 是具有对 sample-database-1 数据库的 readWrite 权限的角色,则连接的默认上下文是 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})

使用特定用户对集群进行身份验证时,还可以在连接字符串中指定数据库。如果这样做,则用户在通过 admin 数据库的身份验证后,不再需要执行 use 命令。

以下连接字符串根据 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:创建对数据库 foo 具有 read 角色的用户。

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

示例 8:创建对特定集合具有读写权限的角色

db.createRole( { role: "collectionRole", privileges: [ { resource: {db: "sample-database-2", collection: "col2"}, actions: ["find", "update", "insert", "remove"] }], roles: [] } )

此操作的输出将类似于下文。

{ "role":"collectionRole", "privileges":[ { "resource":{ "db":"sample-database-2", "collection":"col2" }, "actions":[ "find", "update", "insert", "remove" ] } ], "roles":[ ] }

示例 9:创建用户并分配用户定义角色

db.createUser( { user: "user3", pwd: "abc123", roles: [] }) db.grantRolesToUser("user3",["collectionRole"])

示例 10:向用户定义角色授予其他权限

db.grantPrivilegesToRole( "collectionRole", [ { resource: { db: "sample-database-1", collection: "col1" }, actions: ["find", "update", "insert", "remove"] } ] )

示例 11:删除用户定义角色的权限

db.revokePrivilegesFromRole( "collectionRole", [ { resource: { db: "sample-database-1", collection: "col2" }, actions: ["find", "update", "insert", "remove"] } ] )

示例 12:更新现有用户定义角色

db.updateRole( "collectionRole", { privileges: [ { resource: {db: "sample-database-3", collection: "sample-collection-3"}, actions: ["find", "update", "insert", "remove"] }], roles: [] } )

功能差异

在 Amazon DocumentDB 中,用户和角色定义存储在 admin 数据库中,而且根据 admin 数据库对用户进行身份验证。此功能与 MongoDB 社区版不同,但与 MongoDB Atlas 一致。

Amazon DocumentDB 还支持变更流,该功能提供按时间顺序排列的更改事件,这些事件在您的集集群合中发生。listChangeStreams 操作应用于集群级别(即跨所有数据库),modifyChangeStreams 操作可以应用于数据库级别和集群级别。

限制

下表包含 Amazon DocumentDB 中基于角色的访问控制的限制。

描述 限制
每个集群的用户数 1000
与用户关联的角色数 1000
用户定义角色数 100
与权限关联的资源数 100

使用基于角色的访问控制进行数据库访问

借助基于角色的访问控制,您可以创建一个用户并向其授予一个或多个角色,以确定该用户可以在数据库或集群中执行哪些操作。

以下是 Amazon DocumentDB 中目前支持的内置角色的列表。

注意

在 Amazon DocumentDB 4.0 和 5.0 中,ListCollectionListDatabase 命令可以选择使用 authorizedCollectionsauthorizedDatabases 参数列出用户有权访问分别需要 listCollectionslistDatabase 角色的集合和数据库。此外,用户现在可以在不需要 KillCursor 角色的情况下终止自己的游标。

Database user
角色名称 描述 操作
read 授予用户对指定数据库的读取权限。

changeStreams

collStats

dbStats

find

killCursors

listIndexes

listCollections

readWrite 授予用户对指定数据库的读取和写入访问权限。

使用 read 权限的所有操作。

createCollection

dropCollection

createIndex

dropIndex

insert

killCursors

listIndexes

listCollections

remove

update

Cluster user
角色名称 描述 操作
readAnyDatabase 授予用户对集群中所有数据库的读取权限。

使用 read 权限的所有操作。

listChangeStreams

listDatabases

readWriteAnyDatabase 授予用户对集群中所有数据库的读写权限。

使用 readWrite 权限的所有操作。

listChangeStreams

listDatabases

userAdminAnyDatabase 授予用户为所有用户分配或修改对指定数据库的角色或权限的能力。

changeCustomData

changePassword

createUser

dropRole

dropUser

grantRole

listDatabases

revokeRole

viewRole

viewUser

dbAdminAnyDatabase 授予用户对所有指定数据库执行数据库管理角色的能力。

使用 dbAdmin 权限的所有操作。

dropCollection

listDatabases

listChangeStreams

modifyChangeStreams

Superuser
角色名称 描述 操作
root 授予用户对以下所有角色的合并资源和操作的访问权限: readWriteAnyDatabasedbAdminAnyDatabaseuserAdminAnyDatabaseclusterAdminrestorebackup

使用 readWriteAnyDatabasedbAdminAnyDatabaseuserAdminAnyDatabaseclusterAdminrestorebackup 的所有操作。

Database administrator
角色名称 描述 操作
dbAdmin 授予用户对指定数据库执行管理任务的能力。

bypassDocumentValidation

collMod

collStats

createCollection

createIndex

dropCollection

dropDatabase

dropIndex

dbStats

find

killCursors

listIndexes

listCollections

modifyChangeStreams

dbOwner 通过合并角色 dbAdminreadWrite 授予用户对指定数据库执行任何管理任务的能力。

使用 dbAdminreadWrite 的所有操作。

Cluster administrator
角色名称 描述 操作
clusterAdmin 通过合并 clusterManagerclusterMonitorhostManager 角色授予用户最大的集群管理访问权限。

使用 clusterManagerclusterMonitorhostManager 的所有操作。

listChangeStreams

dropDatabase

modifyChangeStreams

clusterManager 授予用户对指定集群执行管理和监控操作的能力。

listChangeStreams

listSessions

modifyChangeStreams

replSetGetConfig

clusterMonitor 授予用户对监控工具可具有只读访问权限的能力。

collStats

dbStats

find

getParameter

hostInfo

indexStats

killCursors

listChangeStreams

listCollections

listDatabases

listIndexes

listSessions

replSetGetConfig

serverStatus

top

hostManager 授予用户监视和管理服务器的能力。

auditConfigure

killCursors

killAnyCursor

killAnySession

killop

Backup administrator
角色名称 描述 操作
backup 授予用户备份数据所需的访问权限。

getParameter

insert

find

listChangeStreams

listCollections

listDatabases

listIndexes

update

restore 授予用户还原数据所需的访问权限。

bypassDocumentValidation

changeCustomData

changePassword

collMod

createCollection

createIndex

createUser

dropCollection

dropRole

dropUser

getParameter

grantRole

find

insert

listCollections

modifyChangeStreams

revokeRole

remove

viewRole

viewUser

update