场景:某项目用了mongodb,然后mongodb一切都是按照默认设置,一切都好,但某日被查出安全漏洞,说mongodb要设置用户和密码什么的

解决方案:自然就是在mongodb里面设置密码,但是遇到了不少的坑,其中最大的坑就是mongodb的3.X身份验证方式,搜了很多文章都没有提到这一点,光说了如何建立用户名密码,却没有考虑到项目连接的需求,导致建立了用户,客户端可以连,怎么操作都是好的,但项目就是连不上,死活报权限验证失败

 

mongodb设置用户密码的过程:

1、首先正常启动mongodb,然后用mongo.exe或者mongo(linux下)来连接mongodb

2、连接进去之后,先改mongodb的身份验证方式,mongodb2.X版本用的是MONGODB-CR方式,而3.X用的是SCRAM-SHA-1方式,这个不修改的话,项目里面的第三方包无法使用用户名密码方式连接mongodb (就算你用户名密码所有参数全对,也会报权限验证失败),这是修改身份验证方式的指令(一共4行,一行一行输入进去即可):

use admin
var schema = db.system.version.findOne({"_id" : "authSchema"})
schema.currentVersion = 3
db.system.version.save(schema)

3、改完之后,切换到你需要的库下面,新建用户(下面指令中的readWrite是意思是读写权限,一般业务来说,读写权限足够了,有需要其他权限自行百度)

use mydatabase
db.createUser({user:"用户名",pwd:"密码",roles:[{role:"readWrite",db:"数据库名称"}]})

新建用户完成,就可以退出mongodb了,然后修改mongodb启动的配置文件,在最后加上--auth ,重新启动mongodb(如果用配置文件方式的话也可以,具体的指令可以去搜一下)

4、mongodb的准备已经做完了,下面就是项目方面的准备,这里以java连接mongodb为例,放个工具类

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;


public class MongoClients {

    public static MongoClient mongoClient=null;

    public static MongoClient init(){
        InputStream in=null;
        Properties pro=null;
        MongoClient client=null;
        try {
           
            String host = "127.0.0.1";//mongodb的地址
            int port = 8080;//端口
            String pwd="1";//密码
            String user="myuser";//用户名
            String db="mydb"//数据库名
            //如果没有用户名密码和数据库名,说明是无保护的mongodb,则不需要账号密码数据库连接
            if(isEmpty(pwd)||isEmpty(user)||isEmpty(db)){
                client= new MongoClient(host, port);
                return client;
            }

            //ServerAddress()两个参数分别为 服务器地址 和 端口
            ServerAddress serverAddress = new ServerAddress(host,port);
            List<ServerAddress> addrs = new ArrayList<ServerAddress>();
            addrs.add(serverAddress);

            //MongoCredential.createPlainCredential()三个参数分别为 用户名 数据库名称 密码
            MongoCredential credential = MongoCredential.createMongoCRCredential(user, db, pwd.toCharArray());
            List<MongoCredential> credentials = new ArrayList<>();
            credentials.add(credential);
            //返回一个mongoClient对象,可以用这个对象做杂七杂八的事了
            client = new MongoClient(addrs,credentials);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return client;
    }

    public static MongoClient getMongoClient(){
        if(null==mongoClient){
            mongoClient=init();
        }
        return mongoClient;
    }

    /**
     * 判断一个字符串是否为空
     */
    public static boolean isEmpty(String str) {
        return null==str||"".equalsIgnoreCase(str);
    }
}

 

其他知识点

1、mongod是有安全模式和非安全模式区分的,安全模式就是启动时加上 --auth ,非安全模式就是不加。如果你设置了用户名密码,那么就必须开启安全模式,否则无效

2、mongodb中切换数据库:use admin   切换到admin库    切换到其他库只要把后面库名换一下就好

3、新增用户的指令:createUser({user:"",pwd:"",roles:[{role:"",db:""}]})       

user用户名,pwd密码,role是权限,权限有很多种,我这里用readWrite(读写权限)就足够了,db是数据库名

注意大小写,逗号,各种括号缺一不可,引号可以用单引号或者双引号,这个不限制

4、删除用户的指令:dropUser("用户名")

删除用户首先需要关闭安全模式(mongodb不使用--auth启动),然后切换到对应的数据库(use 数据库名),然后用上面的指令删除用户

5、忘记用户名密码了怎么办?只能删用户重建(不过删除用户不影响数据),查看用户的指令,我这里不列举了,自己搜索