前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET Core应用如何通过SSL访问MongoDB?

.NET Core应用如何通过SSL访问MongoDB?

作者头像
Edison Zhou
发布2022-12-18 18:25:51
8390
发布2022-12-18 18:25:51
举报
文章被收录于专栏:EdisonTalkEdisonTalk

大家好,我是Edison。

最近有一个ASP.NET Core通过SSL证书访问MongoDB的需求,但是在网上发现资料很少,于是调查了一番,做了如下的笔记,希望对你有用。

背景

在实际场景中,开发环境的MongoDB服务器一般没有要求通过SSL方式来登陆,但是生产环境的MongoDB服务器通常都会基于安全要求基于SSL方式来访问,这就要求客户端应用需要通过SSL证书来和MongoDB服务器进行通信验证后才能正常读取和写入数据。

那么,在ASP.NET Core应用中应该如何修改匹配呢?今天,我们就来看一看。

修改

通过学习MongoDB.Driver后,在实例化MongoClient时可以通过传递一个MongoClientSettings类来进行自定义参数的实例化,而这个MongoClientSettings类提供的参数比较丰富,我们可以将这些参数配置在appsettings中进行分环境的自定义。

代码语言:javascript
复制
var mongoClient = new MongoClient(new MongoClientSettings());

因此,我们可以写一个MongoSettings类来读取appsettings中的配置生成一个MongoClientSettings,这里给出一个参考示例。

代码语言:javascript
复制
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对象:

代码语言:javascript
复制
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中的配置绑定:

代码语言:javascript
复制
builder.Services.Configure<MongoSettings>(
    builder.Configuration.GetSection("MongoDatabase"));
builder.Services.AddSingleton(sp =>
    sp.GetRequiredService<IOptions<MongoSettings>>().Value);
......
builder.Services.AddSingleton<ITodoItemRepository, TodoItemRepository>();

针对Development环境的appsettings:

代码语言:javascript
复制
{
  ......   
  "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:

代码语言:javascript
复制
{
  ......   
  "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官方文档

作者:周旭龙

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 修改
  • 小结
  • 参考资料
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档