MongoDB 分账号限制数据访问
在 MongoDB 中,可以通过几种方式实现不同账号只能访问特定数据的需求,类似于你在 PostgreSQL 中实现的功能。
1. 基于角色的访问控制 (RBAC)
创建用户并分配角色
// 创建只能读取特定数据库的用户
use admin
db.createUser({
user: "restricted_user",
pwd: "secure_password",
roles: [
{ role: "read", db: "your_database" }
]
})
创建自定义角色限制集合访问
use admin
db.createRole({
role: "org_123_restricted_role",
privileges: [
{
resource: { db: "your_database", collection: "hs_report_task" },
actions: ["find"]
},
{
resource: { db: "your_database", collection: "hs_recipel" },
actions: ["find"]
},
{
resource: { db: "your_database", collection: "hs_recipel_item" },
actions: ["find"]
}
],
roles: []
})
// 将角色分配给用户
db.grantRolesToUser("restricted_user", ["org_123_restricted_role"])
2. 使用视图限制数据访问 (MongoDB 3.4+)
// 创建仅包含org_id=123数据的视图
use your_database
db.createView("restricted_hs_report_task", "hs_report_task", [
{ $match: { org_id: 123 } }
])
// 为用户授予视图访问权限
use admin
db.runCommand({
grantRolesToUser: "restricted_user",
roles: [
{ role: "read", db: "your_database", collection: "restricted_hs_report_task" }
]
})
3. 字段级加密 (MongoDB 4.2+ 企业版)
如果需要更高级的安全控制,可以使用客户端字段级加密:
// 创建加密模式
const schema = {
"your_database.hs_report_task": {
bsonType: "object",
encryptMetadata: {
keyId: [UUID("...")],
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
},
properties: {
org_id: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
}
};
// 创建具有特定访问权限的用户
db.createUser({
user: "encrypted_user",
pwd: "secure_password",
roles: [
{ role: "read", db: "your_database" }
],
authenticationRestrictions: [
{
clientSource: ["192.168.1.0/24"],
serverAddress: ["mongodb1.example.com"]
}
]
})
4. 完全禁止访问特定集合
use admin
db.revokeRolesFromUser("restricted_user", [
{ role: "read", db: "your_database", collection: "hs_disce" }
])
最佳实践
- 最小权限原则:只授予必要权限
- 使用自定义角色:而非直接分配内置角色
- 定期审计:检查用户权限
- 结合网络限制:使用authenticationRestrictions限制访问IP
- 启用认证:确保mongod启动时开启了认证(
--auth
参数)
验证设置
// 使用受限用户登录
mongo -u restricted_user -p secure_password --authenticationDatabase your_database
// 在Mongo shell中测试
use your_database
db.hs_report_task.find() // 应该能看到数据
db.hs_disce.find() // 应该被拒绝
这样设置后,restricted_user用户将只能访问指定的三个集合,并且可以通过视图或查询修饰符进一步限制只能看到org_id=123的数据。