本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用角色型存取控制存取資料庫
您可以使用 Amazon DocumentDB 中的角色型存取控制 (RBAC) (具有 MongoDB 相容性),限制使用者可以在資料庫上執行的動作的存取。RBAC通過將一個或多個角色授予用戶來工作。這些角色決定了使用者可以對資料庫資源執行的作業。Amazon DocumentDB 目前支援在資料庫層級範圍設定的內建角色,例如、、和使用者定義的角色 read
readWrite
readAnyDatabase
clusterAdmin
,這些角色可以限定特定動作和精細資源,例如根據您的需求進行集合。
一般使用案例RBAC包括透過建立對叢集中資料庫或集合具有唯讀存取權限的使用者來強制執行最低權限,以及可讓單一使用者存取叢集中指定資料庫或集合的多租用戶應用程式設計。
注意
所有在 2020 年 3 月 26 日之前建立的新使用者均獲授予 dbAdminAnyDatabase
、readWriteAnyDatabase
和 clusterAdmin
角色。建議您重新評估所有現有使用者,並視需要修改角色,以強制執行叢集的最低權限。
RBAC概念
以下是與以角色為基礎的存取控制相關的重要術語與概念。如需 Amazon 文件資料庫使用者的詳細資訊,請參閱。管理 Amazon DocumentDB 用戶
-
使用者 — 可向資料庫驗證並執行作業的個別實體。
-
密碼 — 用來驗證使用者的密碼。
-
角色 — 授權使用者對一或多個資料庫執行動作。
-
管理資料庫 — 儲存和授權使用者的資料庫。
-
Database (
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
。
以下範例顯示在您透過 db.getUser(sample-user)
取得使用者 sample-user
後的輸出 。在此範例中,使用者 sample-user
位於 admin
資料庫中,但具有 sample-database
資料庫的讀取角色。
建立使用者時,如果您在指定角色時省略該db
欄位,Amazon DocumentDB 會隱含地將角色歸因於發出連線的資料庫。例如,如果您的連線是針對資料庫 sample-database
發出,並執行以下命令,則使用者 sample-user
將建立於 admin
資料庫中,並將具有資料庫 sample-database
的 readWrite
許可。
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"
}
]
}
開始RBAC使用使用者定義角色
為了協助您開始使用使用者定義的角色,本節將引導您針對具有不同工作功能的三個使用者建立角色來強制執行最低權限的範例案例。
在此範例中,以下內容適用:
-
user1
是一名新主管,需要能夠檢視和存取叢集中的所有資料庫。 -
user2
是一名新員工,只需要在同一個集群中的一個數據庫中的「查找」操作。sample-database-1
-
user3
是現有員工,需要查看和訪問特定集合,col2 在不同的數據庫中,他們sample-database-2
之前沒有訪問權限,在同一個集群中。 -
對於
user1
,使用下列命令建立對整個叢集中所有資料庫具有讀寫存取權的角色。
db.createUser( { user: "user1", pwd: "abc123", roles: [{role: "readWriteAnyDatabase", db: "admin"}] } )
此操作的輸出將會如下所示。
{ "user":"user1", "roles":[ { "role":"readWriteAnyDatabase", "db":"admin" } ] }
對於user2
,使用下列命令建立具有資料庫sample-database-1
中所有集合「find」權限的角色。請注意,此角色將確保任何關聯的使用者只能執行尋找查詢。
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":[ ] }
接下來,創建 user(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
已經創建,您可以授予user3
該角色collectionFind
。
db.grantRolesToUser("user3",["collectionRole"])
最後,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":"admin", "role":"collectionRole" } ] }
以使用者身分連接到 Amazon DocumentDB
連線到 Amazon DocumentDB 叢集時,您可以在特定資料庫的環境中進行連線。根據預設,如果您未在連線字串中指定資料庫,則會自動連接到 test
資料庫內容中的叢集。會對 test
資料庫中的集合發出所有像 insert
和 find
之類的集合層級命令。
要查看您在上下文中的數據庫,或者(換句話說)發出命令,請使用 mongo shell 中的db
命令,如下所示。
查詢:
db
輸出:
test
雖然預設連線可能在 test
資料庫的內容中,但這並不一定表示與連線關聯的使用者有權對 test
資料庫執行動作。在上述範例案例中,如果您以具有 sample-database-1
資料庫 readWrite
角色的使用者 user3
身分驗證,則連線的預設內容是 test
資料庫。不過,如果您嘗試將文件插入 test
資料庫上的集合中,您會收到授權失敗的錯誤訊息。這是因為該使用者未獲權在該資料庫上執行該命令,如下圖所示。
查詢:
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:建立具有資料庫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
範例 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 Community Edition,但與 MongoDB Atlas 一致。
Amazon DocumentDB 也支援變更串流,可提供叢集集合中發生的變更事件依時間順序順序排列。listChangeStreams
動作會在叢集層級 (也就是跨所有資料庫) 套用,而且modifyChangeStreams
動作可在資料庫層級和叢集層級套用。
限制
下表包含 Amazon DocumentDB 中以角色為基礎的存取控制的限制。
描述 | 限制 |
---|---|
每個叢集的使用者數目 | 1000 |
與使用者相關聯的角色數目 | 1000 |
使用者定義的角色數 | 100 |
與權限相關聯的資源數 | 100 |
使用角色型存取控制存取資料庫
您可以使用以角色為基礎的存取控制建立使用者並授予其一或多個角色,以決定使用者可以在資料庫或叢集中執行哪些操作。
以下是目前支援的內建角 Amazon DocumentDB。
注意
在 Amazon DocumentDB 4.0 和 5.0 中,ListCollection
和ListDatabase
命令可以選擇性地使用authorizedCollections
和authorizedDatabases
參數列出使用者在需要和listDatabase
角色的情況下有權存取的集合listCollections
和資料庫。此外,使用者現在可以在不需要KillCursor
角色的情況下殺死自己的游標。