修改mongodb3.0副本集用户密码遇到的坑

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

最近公司对项目安全方面的问题很是重视,进行了多次各种安全漏洞的扫描,于是乎就扫到了mongodb弱口令的问题。

 

在项目部署初期,因为大家对这个都不是特别重视,大概是因为觉得反正是内网项目吧,所以mongodb数据库的用户名和密码就都是admin。

 

这次扫到弱口令之后,要求解决这个问题,于是任务便分到了我的头上。

 

遵循强口令的标准,我把admin改成了由大写字母、小写字母、数字和特殊字符共同组成的密码,但是在更改的过程中却并不像想象的那么顺利,其中遇到的问题我称之为mongodb副本集密码的一些坑。

 

坑在哪里呢?首先是修改密码的过程,因为是副本集的缘故,所以理论上是更改数据的时候只需要更改主库就好,然后从库就会自动同步。

 

于是我便想到直接更改用户信息中的密码内容,但是密码信息是保存在db.system.users中,这个数据用户似乎是无权进行更改操作的。

 

虽然之前就知道这个权限的问题,但是我还是想试一下,毕竟之前我没有改过副本集的密码,也不确定究竟可不可行。

 

而尝试的结果证明这个内容确实是无权修改,我用db.system.users.update更改时,提示权限不足:

WriteResult({
       "writeError" : {
                "code" : 13,
                "errmsg" : "notauthorized on admin to execute command { update: \"system.users\",updates: [ { q: { user: \"admin\" }, u: { $set: { pwd:\"123456\" } }, multi: false, upsert: false } ], ordered: true}"
       }
})


于是我便想到,不如我把之前的用户删掉,然后再重新创建,这样的话总该没有问题了吧。但实际上我这样做的时候,当我删除了admin用户之后,再来createUser时,提示我用户验证不通过。

 

因为我之前只创建了这一个用户,因此便只好关闭了进程,然后都以不启动用户认证的方式启动mongodb,之后再次建立用户,这样操作之后终于成功换成新的密码。

 

在此之后,我突然想到是不是可以在两个用户的情况下用前边不成功的方法来修改密码呢?于是我就做了二次尝试,创建了两个用户。

 

然后我便发现果然如猜测的那样,当我用某个用户验证时,是可以删除另外一个并再次创建的,这个时候就不会像一个用户那样在删除后重建时,提示验证问题(当然了用户角色需要正确的选择)。

 

鉴于上边的内容,我想也完全可以有第三种做法,因为我是不改用户名的情况下操作,而如果连用户名和密码一起改,那么也就不用如此麻烦了,可以直接创建用户便好。

 

那么第二个坑就是,这个密码中的特殊字符似乎有一定的限制,我在命令行操作时没有任何问题,但是当我用spring中的代码连接时,直接启动就报错,提示”&”符有问题。

 

之前的spring连接mongodb的代码是这样:

<mongo:mongo-client replica-set="192.168.91.27:27017" credentials="admin:admin@admin" id="mongo"> 
       <mongo:client-options write-concern="SAFE" connections-per-host="100"
            threads-allowed-to-block-for-connection-multiplier="50"
              /> 
</mongo:mongo-client> 

第二个admin代表密码,我把这个admin改成新的带有“&”的密码(例如“aaa&123$_”)便出了如下问题:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import beandefinitions from relative location [spring-mongodb305.xml]
Offending resource: class pathresource [spring.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from class path resource[spring-mongodb305.xml] is invalid; nested exception is org.xml.sax.SAXParseException;lineNumber: 15; columnNumber: 102; 在实体引用中, 实体名称必须紧跟在 '&' 后面。
    atorg.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:76) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:274) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:199) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:141) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:110) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125) ~[spring-web-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94) ~[spring-web-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129) ~[spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:540) ~[spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454) ~[spring-context-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381) ~[spring-web-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293) ~[spring-web-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994) [catalina.jar:7.0.57]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492) [catalina.jar:7.0.57]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565) [catalina.jar:7.0.57]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from class path resource[spring-mongodb305.xml] is invalid; nested exception isorg.xml.sax.SAXParseException; lineNumber: 15; columnNumber: 102; 在实体引用中, 实体名称必须紧跟在 '&' 后面。
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:398) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:258) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    ... 28 common frames omitted
Caused by: org.xml.sax.SAXParseException: 在实体引用中, 实体名称必须紧跟在 '&' 后面。
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177) ~[na:1.7.0_79]
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1436) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(XMLScanner.java:885) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanAttribute(XMLNSDocumentScannerImpl.java:439) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:255) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) ~[na:1.7.0_79]
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) ~[na:1.7.0_79]
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) ~[na:1.7.0_79]
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243) ~[na:1.7.0_79]
    atcom.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347) ~[na:1.7.0_79]
    atorg.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:76) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:428) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    atorg.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) ~[spring-beans-4.0.0.RELEASE.jar:4.0.0.RELEASE]
    ...31 common frames omitted


于是我只好把密码中的”&”去掉,换成其他特殊字符,重新更改了数据库中的用户密码,然后再次启动时一切便正常了。

 

当然了,这样改了问题是暂时解决了,项目也正常的运行起来,但是我却没有弄明白为什么要这样改,于是之后一顿百度后,我发现原来根源的问题并不是mongodb密码的问题,而是xml的问题。

 

在xml中&有特殊的含义,因此要么不用,要么就要使用&amp代替,原来如此,这个坑实际上是因为自己知识了解的不够多以及一时间考虑的问题不够,而后自己坑了自己。

 

这样一来也就解释了我心中的另一个疑惑,那就是为什么写在properties中的带“&”的密码就没问题,直接写在xml中就有问题。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
NoSQL MongoDB 索引
MongoDB副本集同步原理
MongoDB的同步原理,官方文档介绍的比较少,网上资料也不是太多,下面是结合官方文档、网上资料和测试时候的日志,整理出来的一点东西。
3333 0
|
18天前
|
监控 NoSQL 算法
【MongoDB】 MongoDB的副本集是什么?
【4月更文挑战第1天】【MongoDB】 MongoDB的副本集是什么?
|
6月前
|
NoSQL MongoDB
MongoDB分片+副本集高可用集群的启停步骤
MongoDB分片+副本集高可用集群的启停步骤
138 0
|
5月前
|
存储 NoSQL Ubuntu
21 MongoDB高级 - 复制(副本集)
21 MongoDB高级 - 复制(副本集)
29 1
|
存储 NoSQL 前端开发
MongoDB——副本集与分片
 MongoDB复制是将数据同步在多个服务器的过程。
845 0
MongoDB——副本集与分片
|
12月前
|
NoSQL 算法 Linux
MongoDB学习笔记(五) 集群搭建之副本集
MongoDB学习笔记(五) 集群搭建之副本集
351 0
|
存储 NoSQL Shell
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(二)
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(二)
251 0
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(二)
|
存储 缓存 NoSQL
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(一)
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(一)
579 0
MongoDB副本集、分片集的伪分布式部署(保姆级教程)(一)
|
运维 NoSQL MongoDB
(3)MongoDB 副本集运维策略
本文聊一聊 MongoDB 副本集运维窗口期的操作策略,最大程度地减少主节点不可用的时间。
|
运维 NoSQL MongoDB
(2)MongoDB副本集自动故障转移原理(含客户端)
前文我们搭建MongoDB三成员副本集,了解集群基本特性,今天我们围绕下图聊一聊背后的细节。
(2)MongoDB副本集自动故障转移原理(含客户端)