多租户MongoDB + mongo-native驱动程序 + 连接池。

5
我们正在尝试使用nodejs/mongo-native驱动程序来实现以下演示文稿中概述的策略(幻灯片13-18)。

https://www.slideshare.net/mongodb/securing-mongodb-to-serve-an-awsbased-multitenant-securityfanatic-saas-application

总之:

  • 从node.js创建到mongodb的连接池。
  • 对于每个租户的请求,从池中获取一个连接并“验证”它。使用验证后的连接来处理请求。响应后,将连接返回到池中。

我能够使用mongo-native驱动程序创建到mongodb的连接池,而不需要指定任何数据库,如下所示:

const client = new MongoClient('mongodb://localhost:27017', { useNewUrlParser: true, poolSize: 10 });

然而,为了获得db对象,我需要执行以下操作:

const db = client.db(dbName);

这是我想要验证连接的地方,但据我所知,这个功能已经被弃用/删除了,更近期的mongo驱动程序、node.js和java都是如此。

根据演示文稿,看起来这在旧版本的Java驱动程序中是可能的。

我是否可以使用单个连接池并使用相同的连接对各个数据库进行验证?

我们的替代方案是为每个租户设置一个连接池,但这对我们目前来说不太有吸引力。

任何帮助都将不胜感激,包括为什么该功能被弃用/移除的原因。

1个回答

6

我在幻灯片上认出你了!:) 我记得那次会议,很有趣。

是的,这个功能已经不能用了,它们在Beta测试期间实施了六个月,之后就放弃了这个优秀的功能。我们不得不改变工作方式...

这很遗憾,因为直到今天,在Mongo中,“连接”(网络内容、SSL和集群识别)和身份验证是两个分开的动作。 想象一下当您运行mongo shell时,您提供主机、端口、副本集 (如果有), 然后您就可以连接上了!但还没有进行身份验证。然后您可以对user1进行身份验证,做一些事情,然后对user2进行身份验证,并且只能做user2可以做的事情。而这都是在同一个连接上完成的!而没有经过创建通道的开销,SSL握手等等......

那时候,驱动程序让我们拥有一个“空白”连接的连接池,我们可以根据当前执行线程的上下文随意地对其进行身份验证。

然后他们停用了这个功能能力,我想这是在Mongo 2.4版本,现在他们只支持在创建时进行身份验证的连接。我们向企业支持部门提出了问题,他们没有说为什么,但对我来说,看起来他们发现这种方式不安全,可能会泄漏“旧”的身份验证信息,并停留在那个“不是那么空白”的可重用连接上。

我们在多租户基础设施实现中做出了变化,从一个大的空白连接池到许多(小)已认证连接的池,每个租户一个池。这些按租户分配的池可以非常小,例如3或5个连接。这个解决方案很好地扩展到数百个租户,但为了满足成千上万的租户,我们必须进行各种优化,根据需要创建池,在空闲时间后关闭它们,对于非活动或休眠的租户进行惰性创建等等。这使我们能够进一步扩展...... 我们仍在寻找解决方案和优化方法。

您始终可以回到Mongo用户的全局池中,该用户具有访问多个数据库的权限。是的,您可以在同一接受身份验证的连接上切换数据库。但是您无法切换身份验证.. 这是纯Mongo Java驱动程序的示例,我们使用Spring提供类似的功能:

MongoClient mongoClient = new MongoClient();
DB cust1db = mongoClient.getDB("cust1");
cust1db.get...
DB cust2db = mongoClient.getDB("cust2");
cust2db.get...

与此有关,我建议您查看MongoDB加密技术,这是一项企业级功能。它是根据不同的密钥来加密每个数据库(每个客户)的唯一方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接