使用mongo-java-driver使用x509证书对MongoDB v2.6进行身份验证时遇到问题

我很难使用x509证书连接到mongo v2.6,以便从Java / Groovy进行身份验证.我用ssl构建了mongo并觉得我已经正确配置了它.

我们的项目有两个连接到Mongo的应用程序 – 一个用NodeJS编写,另一个用Java / Groovy编写. NodeJS项目成功地使用X509证书和查询进行身份验证.另外,我可以通过指定ssl并在命令行上提供PEM文件来shell到mongo.但是,我无法使用Java Mongo驱动程序连接到mongo.我非常感谢一些帮助,以下是我迄今采取的步骤:

构建MongoDB 2.6以使用SCONS与ssl一起运行:

我从mongodb github页面下载了2.6版本的MongoDB

然后,使用scons构建它以包含ssl

scons --64 --dd --ssl all
scons --ssl --prefix=/opt/mongo  install

为Mongo生成密钥::

我生成了以下密钥/证书

openssl req -new -newkey rsa:1024 -nodes -out myMongo.req -keyout myMongo.key -subj "/C=US/ST=myState/CN=myMongo/OU=myUnit/L=myLocation" -days 36500
openssl x509 -CA myCA.pem -CAkey myCa.key -CAserial myCa.srl -req -in myMongo.req -out myMongo.pem -days 36500

这给了我以下文件:

> myMongo.key(包含私钥)
> myMongo.pem(包含证书)
> myMongo.req(包含证书请求)(我不确定我是否需要这个,还没有使用它)

根据mongo指令,我将密钥和证书连接成1个文件

cat myMongo.key myMongo.pem > combined.pem

遵循x509配置的mongo说明:
http://docs.mongodb.org/manual/tutorial/configure-x509/

openssl x509 -in combined.pem -inform PEM -subject -nameopt RFC2253

这给了我一个主题:“C = US,ST = myState,CN = myMongo,OU = myUnit,L = myLocation”
然后,我将该主题添加到数据库中的用户

db.getSiblingDB("$external").runCommand(
  {
    createUser: "C=US,ST=myState,CN=myMongo,OU=myUnit,L=myLocation",
    roles: [
             { role: 'readWrite', db: 'mydbName' },
             { role: 'userAdminAnyDatabase', db: 'admin' }
           ],
    writeConcern: { w: "majority" , wtimeout: 5000 }
  }
)

在我的mongod.conf文件中,我指定以下选项:

sslMode = requireSSL
sslPEMKeyFile = /path/to/my/combined.pem
sslCAFile = /path/to/myCA.pem

此时,我可以发布

mongod --config /path/to/my/mongod.conf

启动后,我只能通过指定访问shell

mongo --ssl -- sslPEMKeyFile /path/to/my/combined.pem

从Java-Mongo-Driver版本2.12.0连接到MongoDB

我正在尝试按照java-mongo-driver github页面上给出的示例:

https://github.com/mongodb/mongo-java-driver/blob/master/src/examples/example/X509CredentialsExample.java

代码失败,我们将在下面提供一个例外,但是你会尝试通过仅以字符串格式提供DN而不是实际将证书附加到请求来尝试连接,这似乎很奇怪.难道这不能打破X509的全部目的吗?我们查看了Ruby示例并附加了一个pem文件.我的团队了解java密钥库和信任库,如果这就是我们应该做的事情,我会很高兴地发送pem文件.此外,在使用节点驱动程序时,我们绝对指定PEM文件的位置.

最终结果是这样的.我们可以很好地实例化MongoClient,甚至可以使用db对象获取集合.当我们尝试以任何方式查询任何集合时,我们返回一个异常,其消息是“无法连接到任何服务器”.

似乎合乎逻辑的是MongoClientOptions.Builder允许我们添加这些信息,因为它似乎是在其他地方完成的.但是我们对该类进行了反省,以防万一文档中缺少它,并且就我们所知,那里没有任何与x509相关的内容.

我感谢您的帮助.

解决方法:

在您链接到的示例中,请注意它只是使用SSLSocketFactory.getDefault(),它依赖于JDK定义的系统属性来指定密钥库和信任库,例如

> javax.net.ssl.keyStoreType = pkcs12
> javax.net.ssl.keyStore = / path / to / pkc
> javax.net.ssl.keyStorePassword =
> javax.net.ssl.trustStoreType = jks
> javax.net.ssl.trustStore = / path / to / truststore
> javax.net.ssl.trustStorePassword =

您必须将客户端证书添加到密钥库,并将MongoDB服务器的签名机构证书添加到信任库.

上一篇:java – 在进行身份验证之前,检查Spring-Security中的X509证书吊销状态


下一篇:如何在PHP中创建数字证书并导出到.p12文件?