大家好,我是Edison。

最近,在使用CAP事件总线时,碰到了这样一个需求:微服务采用的是MongoDB,而且还是带身份验证 和 SSL根证书验证的。由于目前网上能找到的资料,都是不带身份验证的MongoDB,现在网络信息安全越来越被重视,那么就需要自己研究一番了。

CAP.MongoDB组件

CAP是一个开源的事件总线项目,在.NET社区已经十分流行了,它提供了多种存储方式:MSSQL, MySQL, PgSQL,MongoDB等,这里我们主要关注MongoDB。快速安装CAP.MongoDB组件:

PM> Install-Package DotNetCore.CAP.MongoDB

快速集成CAP.MongoDB组件(StartUp.cs):

​public void ConfigureServices(IServiceCollection services)
{
// ...

services.AddCap(x =>
{
x.UseMongoDB(opt=>{
//MongoDBOptions
});
// x.UseXXX ...
});
}

目前CAP提供的Options如下:

也就是说,CAP的Option只提供了一个DatabaseConnection选项,让我们自己构造Mongo链接字符串供CAP使用。

那么,我们就需要准确地构造这个Mongo连接字符串了。

这里,我们以之前分享的一篇文章《在ASP.NET 6中使用工作单元操作MongoDB》为基础,不熟悉的朋友可以先看看这篇文章。

前提条件/准备工作

这里我们假设在appsettings中我们针对MongoDB的配置项如下格式:

"MongoDatabaseConfigs": {
"Servers": "xxx01.server.net,xxx02.server.net,xxx03.server.net",
"Port": 27017, // optional, default : 27017
"ReplicaSetName": "myrs",
"DatabaseName": "TEST_DB",
"AuthDatabaseName": "admin", // optional, default: admin
"ApplicationName": "Todo",
"UserName": "test_dev_user",
"Password": "test_dev_password",
"UseTLS": true, // optional, default : false
"AllowInsecureTLS": true, // optional, default : true
"SslCertificatePath": "/etc/pki/tls/certs/MyCustomCA.cer"
}

配置项中给出了UserName、Password 还有 SSL证书的路径,这些都是需要构造到连接字符串中的。当然,在Kubernetes中,都建议放到Secret中去。

核心工作:封装构造连接字符串的方法

这里我们封装一个生成MongoDB连接字符串的静态方法,用于读取appsettings中的配置项,并帮我们生成CAP可以用的MongoDB连接字符串:

public static class DbConnUtil
{
// Const Settings for Mongo
private const int DEFAULT_CONNECT_TIMEOUT_MS = 10000; // 10s
private const int DEFAULT_SERVER_SELECTION_TIMEOUT_MS = 5000; // 5s
private const string DEFAULT_AUTH_MECHANISM = "SCRAM-SHA-256"; // SCRAM-SHA-256
private const string DEFAULT_READ_PREFERENCE = "primaryPreferred"; // Primary Preferred
private const string DEFAULT_SSL_INVALID_HOSTNAME_ALLOWED = "true"; // Allow Invalid HostName for SSL /// <summary>
/// 获取MongoDB数据库连接字符串
/// 需要在配置文件中提前根据指定Key进行设置
/// </summary>
public static string GetMongoDbConnectionString(IConfiguration config)
{
var servers = config["MongoDatabaseConfigs:Servers"];
var port = config["MongoDatabaseConfigs:Port"] ?? "27017";
if (string.IsNullOrWhiteSpace(servers))
throw new ArgumentNullException("Mongo Servers Configuration is Missing!");
var mongoServers = servers.Split(','); // Basic Auth
var userName = config["MongoDatabaseConfigs:UserName"];
var password = config["MongoDatabaseConfigs:Password"];
if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
throw new ArgumentNullException("Mongo Account Configuration is Missing!"); // Uri
var replicaName = config["MongoDatabaseConfigs:ReplicaSetName"];
var authDatabaseName = config["MongoDatabaseConfigs:AuthDatabaseName"] ?? "admin";
var mongoUriBuilder = new StringBuilder();
mongoUriBuilder.Append($"mongodb://{userName}:{password}@");
for (int i = 0; i < mongoServers.Length; i++)
{
if (i < mongoServers.Length - 1)
{
mongoUriBuilder.Append($"{mongoServers[i]}:{port},");
}
else
{
mongoUriBuilder.Append($"{mongoServers[i]}:{port}/?");
}
} // Settings
var applicationName = config["MongoDatabaseConfigs:ApplicationName"];
mongoUriBuilder.Append($"replicaSet={replicaName}");
mongoUriBuilder.Append($"&appName={applicationName}");
mongoUriBuilder.Append($"&authSource={authDatabaseName}");
mongoUriBuilder.Append($"&authMechanism={DEFAULT_AUTH_MECHANISM}");
mongoUriBuilder.Append($"&connectTimeoutMS={DEFAULT_CONNECT_TIMEOUT_MS}");
mongoUriBuilder.Append($"&serverSelectionTimeoutMS={DEFAULT_SERVER_SELECTION_TIMEOUT_MS}");
mongoUriBuilder.Append($"&readPreference={DEFAULT_READ_PREFERENCE}"); // TLS/SSL Auth
var useTLS = Convert.ToBoolean(config["MongoDatabaseConfigs:UseTLS"] ?? "false");
if (useTLS)
{
var allowInsecureTls = Convert.ToBoolean(config["MongoDatabaseConfigs:AllowInsecureTLS"] ?? "true");
var sslCertificatePath = config["MongoDatabaseConfigs:SslCertificatePath"]; mongoUriBuilder.Append($"&ssl={useTLS}");
mongoUriBuilder.Append($"&net.ssl.CAFile={sslCertificatePath}");
mongoUriBuilder.Append($"&net.ssl.allowInvalidCertificates={DEFAULT_SSL_INVALID_HOSTNAME_ALLOWED}");
} return mongoUriBuilder.ToString();
}
}

最终可以生成的连接字符串为:

mongodb://test_dev_user:test_dev_password@xxx01:27017.server.net,xxx02.server.net:27017,xxx03.server.net:27017/?replicaSet=myrs&appName=Todo&authSource=admin&authMechanism=SCRAM-SHA-256&connectTimeoutMS=10000&serverSelectionTimeoutMS=5000&readPreference=primaryPreferred&ssl=True&net.ssl.CAFile=/etc/pki/tls/certs/MyCustomCA.cer&net.ssl.allowInvalidCertificates=true

ASP.NET Core集成CAP

这里我们使用刚刚封装的方法来生成Mongo连接字符串,来快速集成CAP:

public static IServiceCollection AddApplicationEventBus(this IServiceCollection services, IConfiguration config)
{
......
// CAP EventBus
services.AddCap(option =>
{
// Transport
option.UseKafka(option =>
{
option.Servers = config["EventBusConfigs:KafkaServers"]
?? throw new ArgumentException("EventBusConfigs:KafkaServers must be set!");
option.ConnectionPoolSize = int.Parse(config["EventBusConfigs:CapConnectionPoolSize"]
?? ApplicationDefaultSettings.Default_ConnectionPool_Size);
option.CustomHeaders = e => new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(Headers.MessageId, SnowflakeId.Default().NextId().ToString()),
new KeyValuePair<string, string>(Headers.MessageName, e.Topic)
}; if (Convert.ToBoolean(config["EventBusConfigs:EnableAuthorization"] ?? "false"))
{
var userName = config["EventBusConfigs:SaslUserName"];
var passWord = config["EventBusConfigs:SaslPassword"]; if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(passWord))
throw new ArgumentNullException("Kafka username or password can't be null!"); option.MainConfig.Add(KafkaMainConfigKey.SECURITY_PROTOCOL, KafkaProtocol.SASL_SSL);
option.MainConfig.Add(KafkaMainConfigKey.SASL_MECHANISM, KafkaAuthMechanism.PLAIN);
option.MainConfig.Add(KafkaMainConfigKey.SASL_USERNAME, userName);
option.MainConfig.Add(KafkaMainConfigKey.SASL_PASSWORD, passWord); if (!string.IsNullOrWhiteSpace(config["EventBusConfigs:SslCertificatePath"]))
option.MainConfig.Add(KafkaMainConfigKey.SSL_CA_LOCATION, config["EventBusConfigs:SslCertificatePath"]);
if (!string.IsNullOrWhiteSpace(config["EventBusConfigs:EnableSslCertificateVerification"]))
option.MainConfig.Add(KafkaMainConfigKey.ENABLE_SSL_CERT_VERIFICATION, config["EventBusConfigs:EnableSslCertificateVerification"]);
}
});
option.SucceedMessageExpiredAfter = 3600 * 24 * int.Parse(config["EventBusConfigs:CapSuccessMsgExpireDays"];
// Storage
option.UseMongoDB(option =>
{
option.DatabaseConnection = DbConnUtil.GetMongoDbConnectionString(config);
option.DatabaseName = config["MongoDatabaseConfigs:DatabaseName"]
?? throw new ArgumentException("MongoDatabaseConfigs:DatabaseName must be set!");
option.PublishedCollection = "msg.published";
option.ReceivedCollection = "msg.received";
});
}); ...... return services;
}

小结

本文我们了解了如何在CAP中集成带基础身份验证(用户名/密码)+SSL根证书验证的MongoDB,方便CAP能够正常连接MongoDB并生成本地消息表,在网络信息安全越来越重视的现在,相信会对你使用CAP+MongoDB有一定帮助!

参考资料

CAP官方文档:https://cap.dotnetcore.xyz/user-guide/en/storage/mongodb/
MongoDB官方文档:https://www.mongodb.com/docs/v5.0/security/

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

CAP项目集成带身份和证书验证的MongoDB的更多相关文章

  1. 无法在web服务器上启动调试。调试失败,因为没有启用集成windows身份验证

    ----注意:以管理员身份运行VS C#中ASP.NET Web应用程序编译时的错误:无法在web服务器上启动调试.调试失败,因为没有启用集成windows身份验证. 解决:打开IIS,在IIS里查看 ...

  2. Spring Cloud系列-Zuul网关集成JWT身份验证

    前言 这两三年项目中一直在使用比较流行的spring cloud框架,也算有一定积累,打算有时间就整理一些干货与大家分享. 本次分享zuul网关集成jwt身份验证 业务背景 项目开发少不了身份认证,j ...

  3. HttpHelpers类普通GET和POST方式,带Cookie和带证书验证模式

    HttpHelpers类普通GET和POST方式,带Cookie和带证书验证模式 参考路径:https://www.cnblogs.com/splendidme/archive/2011/09/14/ ...

  4. Android证书验证存漏洞 开发者身份信息可被篡改(转)

    原帖地址:http://bbs.pediy.com/showthread.php?p=1335278#post1335278 近期在国内网易,雷锋网等网站爆出谷歌市场上的索尼官方的备份与恢复应用&qu ...

  5. 微信支付HTTPS服务器证书验证指引

    1. 背景介绍 2. 常见问题 3. 验证证书 4. 安装证书 背景介绍 微信支付使用HTTPS来保证通信安全, 在HTTPS服务器上部署了由权威机构签发的证书, 用于证明微信支付平台的真实身份. 商 ...

  6. iOS-Cordova集成开发,已有项目集成cordova

    iOS-Cordova集成开发,已有项目集成cordova 项目组准备开发一个APP,要求Android和iOS端页面完全一致,除了一个页面跟业务相关的不同,其他界面基本一致,因此,萌生一个想法,关于 ...

  7. iOS 绕过https证书验证 请求数据

    HTTPS和HTTP: 1.https协议需要到ca申请证书,一般免费证书很少,需要交费. 2.http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议. 3.http ...

  8. Taurus.MVC 微服务框架 入门开发教程:项目集成:4、默认安全认证与自定义安全认证。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  9. 重温WCF之WCF传输安全(十三)(4)基于SSL的WCF对客户端采用证书验证(转)

    转载地址:http://www.cnblogs.com/lxblog/archive/2012/09/20/2695397.html 前一篇我们演示了基于SSL的WCF 对客户端进行用户名和密码方式的 ...

  10. 【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/-fLLTtip509K6pNOTkflPQ 导语 本 ...

随机推荐

  1. x.ai还是OpenAI?埃隆·马斯克的AI帝国【2】

    上期内容咱们提到了埃隆马斯克的特斯拉是自动驾驶领域的领导者,大家可能近些年也都有从各类渠道听到过Tesla自动驾驶有关的新闻.不同于像包括Google子公司Waymo在内的大多数使用激光雷达来实现自动 ...

  2. 第三章 Linux文件与目录结构

    1. Linux 文件 ‍ Linux 系统中一切皆文件. ‍ 2. Linux 目录文件(了解一下) ‍ ​​ ‍ ​​ ‍ ​​ ‍ ​​ ‍ ​​ ‍ ​​ ‍

  3. 基于uni-app+vue3渲染markdown格式|uniapp软键盘顶起问题解决方案

    前些时候有给大家分享一篇uni-app+vite4+uview-plus搭建跨端项目.今天主要分享下在uniapp中渲染markdown语法及uniapp中软键盘弹起,页面tabbar或顶部自定义na ...

  4. Java 字符串反转,举例:键盘录入”abc”输出结果:”cba”

    代码如下: public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out. ...

  5. .Net微服务实战

    前言 第一篇.Net微服务实战是2020年开始的,整个系列拥有文章共11篇,抛开代码计算共有7W多字,每一篇都是我花了不少精力与心思进行打磨. 后续该系列有新增的文章会在此目录同步更新,也是主要方便自 ...

  6. 知识图谱之《海贼王-ONEPICE》领域图谱项目实战(含码源):数据采集、知识存储、知识抽取、知识计算、知识应用、图谱可视化、问答系统(KBQA)等

    知识图谱之<海贼王-ONEPICE>领域图谱项目实战(含码源):数据采集.知识存储.知识抽取.知识计算.知识应用.图谱可视化.问答系统(KBQA)等 实体关系可视化页面可视化页面尝鲜 1. ...

  7. Starting Tomcat v8.0 Server at localhost has encountered a problem.

    现有Tomcat文件夹配置有问题,安装新的tomcat从新启动就好了

  8. 使用wsl 清理windows 下的C盘

    大文件删除思路 ## 在wsl 中可以看到,C盘已经挂载了,挂载点为/mnt/c dewan@wsl ~% df /mnt/c Filesystem Size Used Avail Use% Moun ...

  9. 一款开源免费、更符合现代用户需求的论坛系统:vanilla

    对于个人建站来说,WordPress相信很多读者都知道了.但WordPress很多时候我们还是用来建立自主发布内容的站点为主,适用于个人博客.企业主站等.虽然有的主题可以把WordPress变为论坛, ...

  10. [mysql]定制封装MySQL的docker镜像

    前言 基于MySQL的原版镜像做一些个性化配置修改,封装/etc/my.cnf文件到镜像中,并且支持通过环境变量修改innodb_buffer_pool_size.server_id以及自动配置inn ...