javascript - Meteor.js 使用 X509 证书身份验证连接到 Mongo

我正在尝试在 Meteor.js 应用程序和 Mongo 服务器之间设置无密码身份验证。

为此,我需要向连接提供 pem 和 crt 文件。 MONGO_URL 连接字符串只需要 parameters关于如何执行身份验证,但没有引用带有证书的文件。我假设,我需要将证书文件作为参数传递给连接。类似于 here 中的描述.

在 Meteor.js 中怎么做?

基本上我想实现相当于做:

mongo mongo.example.com/example -ssl -sslPEMKeyFile client.pem --sslCAFile server.crt

然后如所述here

db.getSiblingDB("$external").auth(
  {
    mechanism: "MONGODB-X509",
    user: "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"
  }
)

这在使用 mogo 客户端时效果很好,但在 Meteor 中我到目前为止只了解我很可能需要使用下面的连接字符串(或类似的东西)

MONGO_URL=mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509

但问题仍然存在 - 如何将证书传递给连接?

更新:有answer使用 native noddejs mongo 驱动程序处理该问题。问题是 - 如何将它移植到 Meteor。

2015 年 12 月 31 日更新:我已经接受了在定义集合时指向使用不同连接对象的答案。单独为每个集合执行此操作很麻烦,但这似乎是目前唯一可行的方法。此外,如果需要,可能可以创建一些 MySslCollection,其他人可以使用它来继承连接详细信息。这尚未经过测试。

最佳答案

更新的答案(1.4 版及更高版本)

正如另一个答案所指出的,此处的选项自 1.4 版起已更改,您现在可以调用

Mongo.setConnectionOptions({ ... });

请参阅 the documentation了解更多详情。

旧答案(1.4 之前的版本)

这是一个有趣的兔子洞......我想我已经找到了一个解决您的问题的解决方案/解决方法(可能还有其他问题)。

我的解决方法的简要说明是在创建集合时指定 mongodb 服务器选项。这必须在服务器代码上完成,以避免分发您的 ssl key /证书。像这样:

new Mongo.Collection("collection_name", {
    connection: DDP.connect("mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509", {
        server: {
            sslCert:[CERT_CONTENTS],
            sslKey:[KEY_CONTENTS],
            sslValidate:false
        }
    })
});

黑客方法

既然您问是否有一种方法可以做到这一点,而无需为创建的每个集合添加选项,我决定再看一下。我还没有测试过这些方法,但它们看起来很不错,如果很老套的话。

1) 使用 reconnect 方法中未记录的选项参数 passthru 设置一个函数以在连接状态下运行。 https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L996

Tracker.autorun(function () {
  var status = Meteor.status();
  if(status == 'failed')
    Meteor.reconnect({
      server: {
        sslCert:[CERT_CONTENTS],
        sslKey:[KEY_CONTENTS],
        sslValidate:false
      }
    });
});

2) Monkey 修补默认连接代码(我不太确定这是否有效,因为我没有花时间了解 mongo 内部代码何时实际设置)。 https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/remote_collection_driver.js

MongoInternals.defaultRemoteCollectionDriver = _.once(function () {
  var connectionOptions = {
    server: {
      sslCert:[CERT_CONTENTS],
      sslKey:[KEY_CONTENTS],
      sslValidate:false
    }
  };

  var mongoUrl = process.env.MONGO_URL;

  if (process.env.MONGO_OPLOG_URL) {
    connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL;
  }

  if (! mongoUrl)
    throw new Error("MONGO_URL must be set in environment");

  return new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions);
});

获得这些答案的过程:

从您链接的答案开始,我发现 Meteor 在哪里创建其 MongoDB 连接:https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/mongo_driver.js#L173

然后我找到了调用的位置:https://github.com/meteor/meteor/blob/3d2282d9ad0b570b913a70d215cd968019d912df/packages/mongo/remote_collection_driver.js#L4

追踪调用的位置让我发现 Collections 实例化了连接:https://github.com/meteor/meteor/blob/15cdbca24888bfdff3ad43c1891a1719c09b3dc5/packages/mongo/collection.js#L102

我可以从那里看到一些选项可以覆盖使用没有指定选项的默认 Mongo 连接。在 Meteor 文档中查找集合 http://docs.meteor.com/#/full/mongo_collection显示:

Options

connection Object

The server connection that will manage this collection. Uses the default connection if not specified. Pass the return value of calling DDP.connect to specify a different server. Pass null to specify no connection. Unmanaged (name is null) collections cannot specify a connection.

所以查看 DDP.connect 的文档 http://docs.meteor.com/#/full/ddp_connect我们走到了死胡同,因为它只需要一个 url...但是等等...在通过 github 上的代码搜索后,我可以看到 DDP.connect 确实需要一个选项参数:https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L1641

我们的任务就这样结束了。

https://stackoverflow.com/questions/34383970/

相关文章:

javascript - 如何使用 Stripe 在一个操作中同时创建客户和卡片?

mongodb - 在 golang 中连接到远程 mongodb 服务器失败,出现身份验证错误

java - 如何在 mongodb 和 Java 中 $and 两个文档?

MongoDb区域副本集 - 每个区域的主节点?

javascript - 在 MongoDB 中使用原生 ES6 Promise

node.js - mongoose中的位置,mongoDB

node.js - 如何更新 Mongoose 中的特定字段?

java - 如何在 play framework 2.3 中编写 cron 作业

javascript - 在 mongo 中查找上周创建的对象

java - MongoRepository findByCreatedAtBetween 没有返回