.NET Core如何通过SSL访问MongoDB?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET Core如何通过SSL访问MongoDB?相关的知识,希望对你有一定的参考价值。
【.NET Core】| 总结/Edison Zhou
大家好,我是Edison。
最近有一个ASP.NET Core通过SSL证书访问MongoDB的需求,但是在网上发现资料很少,于是调查了一番,做了如下的笔记,希望对你有用。
背景
在实际场景中,开发环境的MongoDB服务器一般没有要求通过SSL方式来登陆,但是生产环境的MongoDB服务器通常都会基于安全要求基于SSL方式来访问,这就要求客户端应用需要通过SSL证书来和MongoDB服务器进行通信验证后才能正常读取和写入数据。
那么,在ASP.NET Core应用中应该如何修改匹配呢?今天,我们就来看一看。
修改
通过学习MongoDB.Driver后,在实例化MongoClient时可以通过传递一个MongoClientSettings类来进行自定义参数的实例化,而这个MongoClientSettings类提供的参数比较丰富,我们可以将这些参数配置在appsettings中进行分环境的自定义。
var mongoClient = new MongoClient(new MongoClientSettings());
因此,我们可以写一个MongoSettings类来读取appsettings中的配置生成一个MongoClientSettings,这里给出一个参考示例。
using MongoDB.Driver;
using System.Security.Cryptography.X509Certificates;
namespace EDT.Todo.Data.Persistance
/// <summary>
/// Generate MongoClientSettings
/// </summary>
public class MongoSettings
public string Servers get; set;
public int Port get; set; = 27017;
public string ReplicaSetName get; set;
public string DatabaseName get; set;
public string DefaultCollectionName get; set; = string.Empty;
public string ApplicationName get; set;
public string UserName get; set;
public string Password get; set;
public string AuthDatabaseName get; set; = string.Empty;
public string CustomProperties get; set; = string.Empty;
public bool UseTLS get; set; = false;
public bool AllowInsecureTLS get; set; = true;
public string ClientCertificatePath get; set; = string.Empty;
public bool StoreCertificateInKeyStore get; set; = false;
public MongoClientSettings GetMongoClientSettings()
if (string.IsNullOrWhiteSpace(Servers))
throw new ArgumentNullException("Mongo Servers Configuration is Missing!");
if (string.IsNullOrWhiteSpace(UserName) || string.IsNullOrWhiteSpace(Password))
throw new ArgumentNullException("Mongo Account Configuration is Missing!");
// Base Configuration
MongoClientSettings settings = new MongoClientSettings
ApplicationName = ApplicationName,
ReplicaSetName = ReplicaSetName
;
// Credential
if (string.IsNullOrWhiteSpace(AuthDatabaseName))
settings.Credential = MongoCredential.CreateCredential(DatabaseName, UserName, Password);
else
settings.Credential = MongoCredential.CreateCredential(AuthDatabaseName, UserName, AuthDatabaseName);
// Servers
var mongoServers = Servers.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
if (mongoServers.Count == 1)
settings.Server = new MongoServerAddress(mongoServers.First(), Port);
settings.DirectConnection = true;
if (mongoServers.Count > 1)
var mongoServerAddresses = new List<MongoServerAddress>();
foreach (var mongoServer in mongoServers)
var mongoServerAddress = new MongoServerAddress(mongoServer, Port);
mongoServerAddresses.Add(mongoServerAddress);
settings.Servers = mongoServerAddresses;
settings.DirectConnection = false;
// SSL
if (UseTLS)
settings.UseTls = true;
settings.AllowInsecureTls = AllowInsecureTLS;
if (string.IsNullOrWhiteSpace(ClientCertificatePath))
throw new ArgumentNullException("ClientCertificatePath is Missing!");
var certs = new List<X509Certificate> new X509Certificate2(ClientCertificatePath) ;
settings.SslSettings = new SslSettings();
settings.SslSettings.ClientCertificates = certs;
settings.SslSettings.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls13;
return settings;
对于原有的Repository类,我们则需要做一点点修改,从IoC容器中获取MongoSettings的实例,并通过调用GetMongoClientSettings方法获取到生成的这个具体的MongoClientSettings对象:
public class TodoItemRepository : ITodoItemRepository
private readonly ILogger<TodoItemRepository> _logger;
private readonly IMongoCollection<TodoItem> _todoItems;
public TodoItemRepository(MongoSettings settings, ILogger<TodoItemRepository> logger)
var mongoClient = new MongoClient(settings.GetMongoClientSettings());
var mongoDatabase = mongoClient.GetDatabase(settings.DatabaseName);
_todoItems = mongoDatabase.GetCollection<TodoItem>(settings.DefaultCollectionName);
_logger = logger;
......
在Program.cs中将MongoSettings和appsettings中的配置绑定:
builder.Services.Configure<MongoSettings>(
builder.Configuration.GetSection("MongoDatabase"));
builder.Services.AddSingleton(sp =>
sp.GetRequiredService<IOptions<MongoSettings>>().Value);
......
builder.Services.AddSingleton<ITodoItemRepository, TodoItemRepository>();
针对Development环境的appsettings:
......
"MongoDatabase":
"Servers": "dev.mongodb01.com,dev.mongodb01.com,dev.mongodb01.com",
"Port": 27017,
"ReplicaSetName": "testrplica",
"DatabaseName": "TestDB",
"DefaultCollectionName": "TodoItems",
"ApplicationName": "Todo",
"UserName": "dev_mongo_user",
"Password": "passwordfordevuser",
"UseTLS": false
针对Production环境的appsettings:
......
"MongoDatabase":
"Servers": "prd.mongo01.com,prd.mongo02.com,prd.mongo03.com",
"Port": 27007,
"ReplicaSetName": "testreplica",
"DatabaseName": "TestDB",
"DefaultCollectionName": "TodoItems",
"ApplicationName": "Todo",
"UserName": "prd_mongo_user",
"Password": "passwordforprduser",
"UseTLS": true,
"AllowInsecureTLS": true,
"ClientCertificatePath": "resources/certificates/intranet_server_ca.cer"
既然是通过证书访问,那么我们得告诉ASP.NET Core这个证书放在什么位置,本文示例是放在这个ASP.NET Core应用目录下的,在实际中建议由运维管理员统一放在一个中心服务器位置,挂载到容器内部可以访问,从而保证证书的安全。如果使用了K8s,还可以将证书作为Secret统一存放。
小结
本文介绍了在ASP.NET Core中如何配置和实现基于SSL证书的方式访问MongoDB数据库,希望对你有所帮助!
参考资料
MongoDB.Driver Doc
年终总结:Edison的2021年终总结
数字化转型:我在传统企业做数字化转型
C#刷题:C#刷剑指Offer算法题系列文章目录
.NET面试:.NET开发面试知识体系
.NET大会:2020年中国.NET开发者大会PDF资料
以上是关于.NET Core如何通过SSL访问MongoDB?的主要内容,如果未能解决你的问题,请参考以下文章
通过 SSL 使用 .net core TestHost/TestServer 调用第三方容器:使用 Testservers CreateClient() 方法绕过 SSL 验证
如何使用自托管 ASP.NET Core 2 应用程序 (httpsys) 进行 HTTPS (SSL)
如何强制 Visual Studio 为运行 Kestrel 的 .NET Core Web 应用程序重新创建 SSL 证书?