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:
- count
对应的mongosh 就是:db.collection.count(query, options)
- find
- listCollections
有了这些知识,比如内置角色role=“read”,它内置了很多Privilege Actions:
-
changeStream
-
collStats
-
dbHash
-
dbStats
-
find
-
killCursors
-
listCollections
-
listIndexes
-
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
这时候成功分配给应用只读的用户了。