MongoDB的权限控制

mongodb的用户

简介

mongodb内部的权限管理采用了 RBAC(Role-Based Access Control)模型。

权限(permission) 关联 角色(role), 然后再给每个用户(user)分配不同的角色, 从而实现了给每个用户分配了对应的权限。

mongodb分配角色的方式是,在哪个库(db)创建了某个用户(user),下次如果要用这个角色(user)连接数据库,就要选择创建这个用户(user)的库(db)作为认证数据库(authentication)

前置条件

如果要让mongodb的权限功能生效,推荐mongodb刚下载完正确的顺序是:

登录mongodb -> 创建root用户 -> 配置文件打开认证功能 -> 重启服务

mongodb默认是不开启认证的,需要打开,否则怎么配置也没用。

./bin/mongod.cfg

security:
  authorization: enabled

例子

创建用户(user)

用户名 “http_client”

use admin // 在db="admin"下创建用户,下次用这个用户登录要指定认证数据库是"admin"
db.createUser(
    {
        user: "http_client", 
        pwd: "123", 
        roles: [
                    {
                        role: "read", 
                        db: "blog"
                    }
            ]
        }
)

查询用户(user)

use admin
db.getCollection("system.users").find({})
{
    "_id" : "admin.http_client",
    "userId" : UUID("3a25eb77-1b3a-4e40-96f8-1051fc5a13e5"),
    "user" : "http_client",
    "db" : "admin",
    "credentials" : {
        "SCRAM-SHA-1" : {
            "iterationCount" : NumberInt(10000),
            "salt" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ=",
            "storedKey" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ=",
            "serverKey" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ="
        },
        "SCRAM-SHA-256" : {
            "iterationCount" : NumberInt(15000),
            "salt" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ=",
            "storedKey" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ=",
            "serverKey" : "aaaaaaaaaaaaaaaaaaaa/hBVpcQ="
        }
    },
    "roles" : [
        {
            "role" : "read",
            "db" : "blog"
        }
    ]
}

比如上面的用户(user)的包含重要信息有:

“user”: “http_client” 表示这个用户(user)叫做"http_client"
“db”: “admin” 表示这个角色(role)是在admin这个库(db)创建的, 下次用这个角色登录要设置"admin"库为认证数据库
“roles[].role” 表示这个用户(user)有角色(role)="read"的权限
“roles[].db” 该角色="read"存在于blog库,需要指定该角色所在的库

用户登录

mongodb://http_client:123@127.0.0.1:27017/?authSource=admin

发现此时登录mongodb后只有读的权限。

内置角色(Built-in Roles)

mongodb存在很多内置的角色,他们有的存在于各个数据库,有的只存在于"admin"库。

以下是部分信息,具体参考 https://www.mongodb.com/docs/manual/reference/built-in-roles/#database-built-in-roles

角色常量权限说明所属数据库
read单库只读(非系统集合)任意数据库
readWrite单库读写任意数据库
readAnyDatabase所有数据库读(除 local/config)仅 admin
readWriteAnyDatabase所有数据库读写(除 local/config)仅 admin
dbAdminAnyDatabase所有数据库管理(如索引、统计, 除 local/config)仅 admin
userAdminAnyDatabase所有数据库的用户管理(除 local/config)仅 admin
root超级权限(含集群管理、所有库读写)仅 admin
backup / restore备份/恢复操作权限仅 admin
clusterAdmin集群最高管理权限(如分片、副本集配置)仅 admin

其中"local/config"库主要存放mongodb内部的信息,比如分片集群的信息,一般业务上用不到。

自定义角色

简介

mongodb基于RBAC原则,里面的Permission对应mongodb的Privilege Actions(https://www.mongodb.com/docs/manual/reference/privilege-actions);

mongodb内部的资源(resource),比如一个数据库,一个表或者一个集群,可以被多个Privilege Actions运用。

比如privilege Action = “find” , 可以执行至少以下mongodb command

  1. count
    对应的mongosh 就是:
    db.collection.count(query, options)
    
  2. find
  3. listCollections

有了这些知识,比如内置角色role=“read”,它内置了很多Privilege Actions

  1. changeStream

  2. collStats

  3. dbHash

  4. dbStats

  5. find

  6. killCursors

  7. listCollections

  8. listIndexes

  9. listSearchIndexes


例子

所以自定义角色可以 针对某个资源(resource) 分配 Privilega Actions

比如:要创建一个role,它只能对数据库db=“blog” 下的 collection="article"表读权限:

创建role

角色 “blog-article-only_role”

use blog // 这里将这个role放到blog库里,之后创建user时候需要设置db="blog"
db.createRole({
  role: "blog-article-only_role",
  privileges: [{
    resource: { db: "blog", collection: "article" },
    actions: ["find"]
  }],
  roles: []
})

查看role

use admin
db.getCollection("system.roles").find({})
{
    "_id" : "admin.blog-article-only_role",
    "role" : "blog-article-only_role",
    "db" : "blog",
    "privileges" : [
        {
            "resource" : {
                "db" : "blog",
                "collection" : "article"
            },
            "actions" : [
                "find"
            ]
        }
    ],
    "roles" : [

    ]
}

创建用户

创建用户 “blog-article-only_user”, 同时赋予角色 " blog-article-only_role"

use test_db // 将这个角色创建在test_db库,登录认证指定为"test_db"
db.createUser(
    {
        user: "blog-article-only_user", 
        pwd: "123", 
        roles: [
                    {
                        role: "blog-article-only_role", 
                        db: "blog"
                    }
            ]
        }
)

用户登录

mongodb://blog-article-only_user:123@127.0.0.1:27017/?authSource=test_db

发现此时登录mongodb后只能对 article 表进行查询。

总结

一般来说mongodb中权限最大的角色是role=“root”, 不应该给应用程式的用户分配root角色,而是应该根据最小权限原则分配具体或者大概的合适权限(如果不确定建议用内置role,而不是自定义避免应用报错)。

比如某个报表系统只会读取数据,该系统使用的用户下的角色是一个只读角色role=“readAnyDatabase”

创建用户 “report”

use admin // 切换到admin,设置该用户认证的库为admin(也可以随便切换到一个库)
db.createUser(
    {
        user: "report", 
        pwd: "123", 
        roles: [
                    {
                        role: "readAnyDatabase", 
                        db: "admin"
                    }
            ]
        }
)

应用程序连接参数应该这样:

mongodb://report:123@127.0.0.1:27017/?authSource=admin

这时候成功分配给应用只读的用户了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值