本文主要介绍了 MongoDB 的账户新建,权限管理(简单的),以及在 Python,Java 和默认客户端中的登陆。
默认的 MongoDB 是没有账户权限管理的,也就是说,不需要密码即可登陆,即可拥有读写的权限(当然,重启服务还是需要在本机执行)。
这个对于自己做实验室足够使用的,但是对于开放数据给他人使用时很不安全的,倒不是怕窃取数据,主要是怕某些猪队友一下把 db 给 drop 了,如果没有容灾备份哭都来不及。
对于 MongoDB 的权限配置,我看着官方文档和别人的笔记也算是踩过坑的人了,把踩过的坑写出来给大家看一下,减少别人踩坑的次数。主要踩的坑还是集中在不同的语言的登陆上,这一方面资料比较少。
首先切换到 admin 数据库
use admin
然后创建一个超级用户,其中 user 和 pwd 的值可以自己随便定义。
- 1 db.createUser(2 {
- 3 user: "super_user",
- 4 pwd: "super_user_paasswd",
- 5 roles: [{
- role: "__system",
- db: "admin"
- }] 6
- }
- 7)
随后我们新建两个用户,一个具有读写权限,一个只有读取的权限。
读写权限的账号给所有需要写数据的服务和程序使用,读取的账号给同事查看和聚集数据的时候使用。
- 1 //新建读账号
- 2 db.createUser({
- 3 "user": "rouser",
- //账号名称
- 4 "pwd": "rouserpwd",
- //密码
- 5 "customData": {
- 6 //注释
- 7 user_abs: "read-only user for data analysis"8
- },
- 9 "roles": [10 {
- 11 role: "readAnyDatabase",
- //读所有数据库
- 12 db: "admin"13
- }
- 14] 15
- },
- {
- 16 w: "majority",
- 17 wtimeout: 5000 18
- }
- 19) 20 //新建读写账号
- 21 db.createUser({
- 22 "user": "rwuser",
- //账号名称
- 23 "pwd": "rwuser_pwd",
- //密码
- 24 "customData": { //注释
- 25 user_abs: "read-write user for data extractor"26
- },
- 27 "roles": [28 {
- 29 role: "readWriteAnyDatabase",
- //读写所有数据库
- 30 db: "admin"31
- }
- 32] 33
- },
- {
- 34 w: "majority",
- 35 wtimeout: 5000 36
- }
- 37)
创建完成以后,首先检查一下是不是新建好了,简单的说,就是看一下 admin 里面是不是记录了你要的用户账户:
- 1 db.getCollection("system.users").find({}) 2 3 //输出:
- 4 //实际输入:db.getCollection("system.users").find({},{"credentials":0})
- 5 {
- "_id": "admin.super_user",
- "user": "super_user",
- "db": "admin",
- "roles": [{
- "role": "__system",
- "db": "admin"
- }]
- }
- 6 {
- "_id": "admin.rouser",
- "user": "rouser",
- "db": "admin",
- "customData": {
- "user_abs": "read-only user for data analysis"
- },
- "roles": [{
- "role": "readAnyDatabase",
- "db": "admin"
- }]
- }
- 7 {
- "_id": "admin.rwuser",
- "user": "rwuser",
- "db": "admin",
- "customData": {
- "user_abs": "read-write user for data extractor"
- },
- "roles": [{
- "role": "readWriteAnyDatabase",
- "db": "admin"
- }]
- }
看到输出了所有的账户信息,就 OK 了,下一步就是重新启动服务,在重启服务之前,需要在 config 文件中设置 `auth = true`,这样才会需要登陆,否则什么都没变
以下是我的 Config 文件,最后一行是重新安装服务的 Command,如果没有安装过,使用 --install 参数即可:
- 1 #存放数据目录
- 2 dbpath=F:\FeaturesData\data
- 3 #日志文件
- 4 logpath=F:\FeaturesData\mongo.log
- 5 #Cache Size
- 6 wiredTigerCacheSizeGB=1
- 7
- 8 auth = true
- 9 logappend = true
- 10 directoryperdb = true
- 11
- 12 #执行
- 13 # mongod --config "F:\FeaturesData\mongo.config" --serviceName "MongoDB" --reinstall
这样启动以后 Mongo 就有权限了,这个时候的登陆要使用账号密码:
mongo" -u super_user -p super_user_paasswd --authenticationDatabase admin 127.0.0.1/test
其中 127.0.0.1/test 是 IP / 数据库名称以连接默认数据库。
这个时候你可以试一下使用只读账号删库或者删集合,会出现 drop failed: MongoError: not authorized on test to execute command
意味着你没有权限删除,这个时候不要说删除,插入操作也是不能做的。
除了使用默认的客户端连接,我们还可以使用其它语言的 Driver 去连接。
这里考虑使用 Python 和 Java 两种情况
首先考虑在 Python 中的连接,我们使用 URI 登陆:
- 1 try:# Python 3.x
- 2 from urllib.parse import quote_plus
- 3 except ImportError:# Python 2.x
- 4 from urllib import quote_plus
- 5 from pymongo import MongoClient
- 6
- 7 #Example
- 8 user = 'USER'
- 9 password = 'PASSWORD'
- 10 host = '127.0.0.1:27017'
- 11 #Code
- 12 uri = "mongodb://%s:%s@%s" % (
- 13 quote_plus(user), quote_plus(password), host)
- 14 client = MongoClient(uri)
再考虑使用 Java 登陆(稍微麻烦一点):
- 1 //这个是我自己封装的读取Properties文件的类
- 2 import com.zjtj.yuanyifan.Util.PropertiesUtil;
- 3 4 import com.mongodb.BasicDBObject;
- 5 import com.mongodb.MongoClient;
- 6 import com.mongodb.MongoCredential;
- 7 import com.mongodb.ServerAddress;
- 8 import com.mongodb.client.FindIterable;
- 9 import com.mongodb.client.MongoCollection;
- 10 11 private MongoCollection getMongoDBConnection() {
- 12 //初始化Mongodb数据库连接,变量名我想不需要解释了
- 13 PropertiesUtil pu = new PropertiesUtil();
- 14 String vfdbname = pu.getPropString("vehicle_features_db_name", "vf");
- 15 String vfdbip = pu.getPropString("vehicle_features_db_ip", "127.0.0.1");
- 16 String vfdbport = pu.getPropString("vehicle_features_db_port", "27017");
- 17 String vfdbuser = pu.getPropString("vehicle_features_db_user", "USER_HERE");
- 18 String vfdbpwd = pu.getPropString("vehicle_features_db_pwd", "PASSWD_HERE");
- 19
- try {
- 20 21 ServerAddress sainfo = new ServerAddress(vfdbip, Integer.valueOf(vfdbport));
- 22 List mgauth = new ArrayList < >();
- 23 mgauth.add(MongoCredential.createCredential(vfdbuser, "admin", vfdbpwd.toCharArray()));
- 24 MongoCollection mgdbc = new MongoClient(sainfo, mgauth).getDatabase(vfdbname).getCollection("daily_features");
- 25 String dbgInfo = String.format("Connected to mongodb://%s:%s/%s/\n", vfdbip, vfdbport, vfdbname);
- 26 System.out.printf(dbgInfo);
- 27 fcc_log.info(dbgInfo);
- 28
- return mgdbc;
- 29
- } catch(Exception ex) {
- 30 String errInfo = "Error while initializing MongoDB connection: " + ex.getMessage();
- 31 System.err.println(errInfo);
- 32 fcc_log.fatal(errInfo);
- 33
- }
- 34
- }
来源: