[ MongoDB ] 3.X权限认证控制

1. 前言

介绍 Mongodb 3.X 的认证控制

2. 环境搭建

[root@192.168.118.16 /usr/local/src]#wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-3.6.11.tgz
[root@192.168.118.16 /usr/local/src]#tar xf mongodb-linux-x86_64-3.6.11.tgz
[root@192.168.118.16 /usr/local/src]#mv mongodb-linux-x86_64-3.6.11 /usr/local/mongodb
[root@192.168.118.16 /usr/local/src]#cd /usr/local/mongodb/
[root@192.168.118.16 /usr/local/mongodb]#mkdir -pv data conf log
mkdir: created directory ‘data’
mkdir: created directory ‘conf’
mkdir: created directory ‘log’

编写配置文件:
[root@192.168.118.16 /usr/local/mongodb/conf]#cat mongod.conf 
bind_ip = 0.0.0.0    # 监听地址
port = 27017    # 监听端口
fork = true    # 后台运行
dbpath = /usr/local/mongodb/data    # 数据存储位置
logpath = /usr/local/mongodb/log/mongodb.log    # 日志存储位置

配置环境变量:
[root@192.168.118.16 /usr/local/mongodb]#cat /etc/profile.d/mongodb.sh
#!/bin/bash
# Author:hukey
export PATH=/usr/local/mongodb/bin:$PATH
[root@192.168.118.16 /usr/local/mongodb]#source /etc/profile.d/mongodb.sh

启动:
[root@192.168.118.16 ~]#mongod -f /usr/local/mongodb/conf/mongod.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 14553
child process started successfully, parent exiting

连接 mongodb
[root@192.168.118.16 ~]#mongo 192.168.118.16

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB

3. 权限控制

首先对mongodb权限认证有个了解:

mongodb - 内置角色:
Built-In Roles(内置角色):
    1. 数据库用户角色:read、readWrite;
    2. 数据库管理角色:dbAdmin、dbOwner、userAdmin;
    3. 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
    4. 备份恢复角色:backup、restore;
    5. 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
    6. 超级用户角色:root  
    // 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)
    7. 内部角色:__system
具体角色:
	Read:允许用户读取指定数据库
	readWrite:允许用户读写指定数据库
	dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
	userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
	clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
	readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
	readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
	userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
	dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
	root:只在admin数据库中可用。超级账号,超级权限

首先,在默认没有开启认证(auth)的前提下,创建一个管理用户的管理员账号,即:账号管理的授权权限

[root@192.168.118.16 ~]#mongod -f /usr/local/mongodb/conf/mongod.conf
[root@192.168.118.16 ~]#mongo 192.168.118.16
> use admin
switched to db admin
> db.createUser({user: 'dba', pwd: 'dba', roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]})
Successfully added user: {
    "user" : "dba",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

查看创建的用户
> show users
{
    "_id" : "admin.dba",
    "user" : "dba",
    "db" : "admin",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

这样就建立了一个 userAdminAnyDatabase 角色,用来管理用户,可以通过这个角色来创建、删除用户。

添加 auth 并启动 mongodb

[root@192.168.118.16 ~]#mongod -f /usr/local/mongodb/conf/mongod.conf --shutdown
[root@192.168.118.16 ~]#mongod -f /usr/local/mongodb/conf/mongod.conf --auth
[root@192.168.118.16 ~]#mongo 192.168.118.16
开启 auth 如果没有验证,导致报错
> show dbs
2020-03-16T11:48:42.045+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "there are no users authenticated",
    "code" : 13,
    "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:67:1
shellHelper.show@src/mongo/shell/utils.js:860:19
shellHelper@src/mongo/shell/utils.js:750:15
@(shellhelp2):1:1

验证,因为是在 admin 下添加的账号,所以需要在 admin 库下验证。
> use admin
switched to db admin
> db.auth('dba', 'dba')
1
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

创建只读用户

> use test
> db.createUser({user:'rr', pwd: '123', roles:[{role: 'read', db: 'test'}]})
Successfully added user: {
    "user" : "rr",
    "roles" : [
        {
            "role" : "read",
            "db" : "test"
        }
    ]
}

创建读写用户

> use test
> db.createUser({user:'ww', pwd: '123', roles:[{role: 'readWrite', db: 'test'}]})
Successfully added user: {
    "user" : "ww",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test"
        }
    ]
}

查看当前库下所有用户

> use test
switched to db test
> show users
{
    "_id" : "test.rr",
    "user" : "rr",
    "db" : "test",
    "roles" : [
        {
            "role" : "read",
            "db" : "test"
        }
    ]
}
{
    "_id" : "test.ww",
    "user" : "ww",
    "db" : "test",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test"
        }
    ]
}

上面添加了两个用户,验证一下,首先使用 读写用户登录: ww/123

> use test
switched to db test
> db.auth('ww','123')
1
> db.abc.insert({'a':1, 'b':2})
WriteResult({ "nInserted" : 1 })
> db.abc.find()
{ "_id" : ObjectId("5e6ef903f055137c529de0d8"), "a" : 1, "b" : 2 }

ww/123 用户只能在 test 库中执行读写操作,无法执行其他任何操作。
> show dbs
2020-03-16T11:57:18.503+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0, lsid: { id: UUID("e73be962-001c-4896-967d-4d3a5ecbd64f") }, $db: "admin" }",
    "code" : 13,
    "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:67:1
shellHelper.show@src/mongo/shell/utils.js:860:19
shellHelper@src/mongo/shell/utils.js:750:15
@(shellhelp2):1:1

读用户:rr/123

> use test
switched to db test
> db.auth('rr','123')
1
> db.abc.find()
{ "_id" : ObjectId("5e6ef903f055137c529de0d8"), "a" : 1, "b" : 2 }

当只读用户执行写操作时,会发生没有授权的错误。
> db.abc.insert({'aa':11,'bb':22})
WriteResult({
    "writeError" : {
        "code" : 13,
        "errmsg" : "not authorized on test to execute command { insert: "abc", ordered: true, lsid: { id: UUID("30ef763c-d883-4793-8a16-2dbcd13b648e") }, $db: "test" }"
    }
})

通过上面的操作,发现某个用户只能在某个库下执行操作,如果需要有夸库操作等,就显得非常不方便。

上面的问题可以通过角色以下权限解决:
	readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
	readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

创建对所有库只读的权限

> use admin
switched to db admin
> db.auth('dba','dba')
1
> db.createUser({user:'anyrr', pwd:'123', roles:[{role: 'readAnyDatabase', db: 'admin'}]})
Successfully added user: {
    "user" : "anyrr",
    "roles" : [
        {
            "role" : "readAnyDatabase",
            "db" : "admin"
        }
    ]
}

验证:在哪个库下创建就需要在哪里去验证

> use admin
switched to db admin
> db.auth('anyrr','123')
1
> show dbs;
admin   0.000GB
beta    0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
> use test
switched to db test
> db.abc.find()
{ "_id" : ObjectId("5e6ef903f055137c529de0d8"), "a" : 1, "b" : 2 }
> use beta
switched to db beta
> db.abc.find()
{ "_id" : ObjectId("5e6efbd8276c4a4cf5aa3f3c"), "aaa" : 111, "bbb" : 222 }


尝试写入数据,因为没有写入权限。
> db.abc.insert({"aaac" : 111, "bbbc" : 222})
WriteResult({
    "writeError" : {
        "code" : 13,
        "errmsg" : "not authorized on beta to execute command { insert: "abc", ordered: true, lsid: { id: UUID("1348e445-d00e-434c-89c9-f363df619855") }, $db: "beta" }"
    }
})

创建对所有库读写的权限

> use admin
switched to db admin
> db.auth('dba','dba')
> db.createUser({user:'anyrw', pwd:'123', roles:[{role: 'readWriteAnyDatabase', db:'admin'}]})
Successfully added user: {
    "user" : "anyrw",
    "roles" : [
        {
            "role" : "readWriteAnyDatabase",
            "db" : "admin"
        }
    ]
}

验证对所有库的读写权限
> use admin
switched to db admin
> db.auth('anyrw', '123')
1
> show dbs
admin   0.000GB
beta    0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
> use test
switched to db test
> db.abc.insert({'x': 123, 'y':345})
WriteResult({ "nInserted" : 1 })
> db.abc.find()
{ "_id" : ObjectId("5e6ef903f055137c529de0d8"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("5e6f106ff60792da65189693"), "x" : 123, "y" : 345 }
> use beta
switched to db beta
> db.abc.insert({'x': 123, 'y':345})
WriteResult({ "nInserted" : 1 })
> db.abc.find()
{ "_id" : ObjectId("5e6efbd8276c4a4cf5aa3f3c"), "aaa" : 111, "bbb" : 222 }
{ "_id" : ObjectId("5e6f1080f60792da65189694"), "x" : 123, "y" : 345 }

在 mongodb 中有一个类似 MySQL root 的权限,能够对mongodb做所有权限的操作

创建 root 权限:
> db.createUser({user: 'root', pwd:'123', roles:[{role: 'root', db: 'admin'}]})
Successfully added user: {
    "user" : "root",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}

验证:
> use admin
switched to db admin
> db.auth('root','123')
1
> show dbs;    # 查看所有库
admin   0.000GB
beta    0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
> use test
switched to db test
> db.abc.find()    # 查看某一个库
{ "_id" : ObjectId("5e6ef903f055137c529de0d8"), "a" : 1, "b" : 2 }
{ "_id" : ObjectId("5e6f106ff60792da65189693"), "x" : 123, "y" : 345 }
> db.drop
db.dropAllRoles(  db.dropAllUsers(  db.dropDatabase(  db.dropRole(      db.dropUser(
> use beta
switched to db beta
> db.abc.find()
{ "_id" : ObjectId("5e6efbd8276c4a4cf5aa3f3c"), "aaa" : 111, "bbb" : 222 }
{ "_id" : ObjectId("5e6f1080f60792da65189694"), "x" : 123, "y" : 345 }
> db.dropDatabase()    # 删除某个库
{ "dropped" : "beta", "ok" : 1 }
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB

> use test
switched to db test
> show users # 查看 test 库的用户
{
    "_id" : "test.rr",
    "user" : "rr",
    "db" : "test",
    "roles" : [
        {
            "role" : "read",
            "db" : "test"
        }
    ]
}
{
    "_id" : "test.ww",
    "user" : "ww",
    "db" : "test",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test"
        }
    ]
}

> db.dropUser('rr')    # 删除某个库下的用户
true
> show users
{
    "_id" : "test.ww",
    "user" : "ww",
    "db" : "test",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "test"
        }
    ]
}

通过上面 root 用户的验证,root权限非常高,慎用!

4.总结

1. 首先在默认没有auth参数的启动下创建管理用户权限的用户,以后添加管理删除用户都使用这个用户操作

db.createUser({user: 'dba', pwd: 'dba', roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]})

2. 为mognodb 添加认证参数并重启生效

关闭mongodb:
mongod -f mognod.conf --shutdown

命令行开启认证服务
mongod -f mongod.conf --auth

配置文件开启认证服务
auth on 
如果是yaml格式则添加 
security: 
  authorization: enabled

3. 权限控制

Read:对某个库的读权限;
use 库名
db.createUser({user:'rr', pwd: '123', roles:[{role: 'read', db: '库名'}]})

ReadWrite:对某个库的读写权限;
use 库名
db.createUser({user:'ww', pwd: '123', roles:[{role: 'readWrite', db: '库名'}]})

readAnyDatabase:对所有库的读权限;
use admin
db.createUser({user:'anyrr', pwd:'123', roles:[{role: 'readAnyDatabase', db: 'admin'}]})

readWriteAnyDatabase:对所有库的读写权限
use admin
db.createUser({user:'anyrw', pwd:'123', roles:[{role: 'readWriteAnyDatabase', db:'admin'}]})

root:开启mongodb最高权限
use admin
db.createUser({user: 'root', pwd:'123', roles:[{role: 'root', db: 'admin'}]})

参考链接:

https://www.cnblogs.com/seasonzone/p/9359501.html

原文地址:https://www.cnblogs.com/hukey/p/12503536.html