Open Closed

Use authMechanism=MONGODB-X509 #8930


User avatar
0
g.maldarelli created
  • ABP Framework version: v9.0.4
  • UI Type: Blazor WASM
  • Database System: MongoDB
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes/no
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I don't find a way to connect into my mongo atlas cluster using a authMechanism=MONGODB-X509 like in this example with standard MongoDB.Driver Version="2.30.0"

//.... var connectionString ="mongodb+srv://xx-mongo.xx.mongodb.net/xx-app-db?retryWrites=true&w=majority&appName=xx-mongo&tls=true&authMechanism=MONGODB-X509"; var settings = MongoClientSettings.FromConnectionString(connectionString); settings.ServerApi = new ServerApi(ServerApiVersion.V1); var cert = new X509Certificate2("atlas-user-cert.pfx","changeit"); settings.SslSettings = new SslSettings { ClientCertificates = new List<X509Certificate>() { cert } }; var client = new MongoClient(settings); //......

Can you help me?

Thanks Giuseppe


5 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you connect your MongoDB in another app/code?

    Do you have any example code of authMechanism=MONGODB-X509?

    Thanks.

  • User Avatar
    0
    g.maldarelli created

    Yes follow a console app that works fine whith the same cluster

    
    using MongoDB.Bson;
    using MongoDB.Driver;
    using System;
    using System.IO;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using System.Security.Cryptography.X509Certificates;
    using System.Text.Json;
    using AtlasCertConnection;
    using AtlasCertConnection.Model.Report;
    using MongoDB.Driver.Linq;
    using TransitalyApp.Shipments;
    using AtlasCertConnection.Model.Types;
    using System.Linq;
    using AtlasCertConnection.Data;
    using AtlasCertConnection.Model;
    using MongoDB.Bson.Serialization;
    
    class Program
    {
        static void Main(string[] args)
        {
            BsonSerializer.RegisterSerializationProvider( new CustomTypeSerializationProvider());
            MainAsync().Wait();
        }
    
        static async Task MainAsync()
        {
            var connectionString =
                "mongodb+srv://ibl-mongo.dizxt.mongodb.net/tri-app-db?retryWrites=true&w=majority&appName=ibl-mongo&tls=true&authMechanism=MONGODB-X509&authSource=%24external";
            var settings = MongoClientSettings.FromConnectionString(connectionString);
            settings.ServerApi = new ServerApi(ServerApiVersion.V1);
    
            var cert = new X509Certificate2(
                "C:\\projects\\development\\IBL\\Trabsitaly\\TransitalyApp\\src\\TransitalyApp.HttpApi.Host\\atlas-user-cert.pfx",
                "changeit");
    
            settings.SslSettings = new SslSettings
            {
                ClientCertificates = new List<X509Certificate>() { cert }
            };
    
            var client = new MongoClient(settings);
            var database = client.GetDatabase("tri-app-db");
            var collection = database.GetCollection<Shipment>("AppShipments");
            var deliveryMinDateThreshold = new DateTime(2025, 3, 1);
            var deliveryMaxDateThreshold = new DateTime(2026, 3, 1);
            var result = collection.Aggregate<Shipment>()
                .Match(Builders<Shipment>.Filter.And(
                    Builders<Shipment>.Filter.Eq("Status", "DELIVERED"),
                    Builders<Shipment>.Filter.Gte("DeliveryExecutedDate", deliveryMinDateThreshold),
                    Builders<Shipment>.Filter.Lte("DeliveryExecutedDate", deliveryMaxDateThreshold)
                ))
                .Sort(new BsonDocument("CreationTime desc", 1))
                .Skip(0)
                .Limit(2000).ToList() ?? [];
    
            Console.WriteLine(result.Count);
            result = PatchNotifyRecipient(result);
            ShippingCostCalculator.GenerateReport(result);
    
    
    
    
        }
    
        private static List<Shipment> PatchNotifyRecipient(List<Shipment> result)
        {
            result.ForEach(shipment =>
            {
                if (shipment.AccessoryServices.FirstOrDefault(s => s.Type == AccessoryServiceType.NOTIFY_RECIPIENT) is null)
                {
                    shipment.AccessoryServices.Add(new AccessoryService
                    {
                        Type = AccessoryServiceType.NOTIFY_RECIPIENT,
                        Description = "Call"
                    });
                }
            });
            return result;
        }
    }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can override the UnitOfWorkMongoDbContextProvider's CreateMongoClient method to change the code of creating MongoClient.

    Add YourUnitOfWorkMongoDbContextProvider : UnitOfWorkMongoDbContextProvider

    Then replace it in DI.

    context.Services.TryAddTransient(
        typeof(IMongoDbContextProvider<>),
        typeof(UnitOfWorkMongoDbContextProvider<>)
    );
    

    https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs#L300-L306

    var connectionString = "mongodb+srv://ibl-mongo.dizxt.mongodb.net/tri-app-db?retryWrites=true&w=majority&appName=ibl-mongo&tls=true&authMechanism=MONGODB-X509&authSource=%24external";
    var settings = MongoClientSettings.FromConnectionString(connectionString);
    settings.ServerApi = new ServerApi(ServerApiVersion.V1);
    
    var cert = new X509Certificate2("C:\\projects\\development\\IBL\\Trabsitaly\\TransitalyApp\\src\\TransitalyApp.HttpApi.Host\\atlas-user-cert.pfx", "changeit");
    
    settings.SslSettings = new SslSettings
    {
        ClientCertificates = new List<X509Certificate>() { cert }
    };
    
    var client = new MongoClient(settings);
    
  • User Avatar
    0
    g.maldarelli created

    the complete solution for future framework improvement:

    `using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Driver; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.OpenSsl; using Org.BouncyCastle.Security; using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; using Volo.Abp.Uow; using Volo.Abp.Uow.MongoDB;

    public class X509CertificateUnitOfWorkMongoDbContextProvider

    public X509CertificateUnitOfWorkMongoDbContextProvider(IUnitOfWorkManager unitOfWorkManager,
        IConnectionStringResolver connectionStringResolver, ICancellationTokenProvider cancellationTokenProvider,
        ICurrentTenant currentTenant, IOptions<AbpMongoDbContextOptions> options,
        IMongoDbContextTypeProvider dbContextTypeProvider, IConfiguration configuration) : base(unitOfWorkManager,
        connectionStringResolver,
        cancellationTokenProvider, currentTenant, options, dbContextTypeProvider)
    {
        _configuration = configuration;
        this.SetX509AuthenticationMechanism();
    }
    
    private void SetX509AuthenticationMechanism()
    {
        var connectionString = _configuration["ConnectionStrings:Default"];
        if (connectionString is not null && connectionString.Contains("authMechanism=MONGODB-X509"))
        {
            useX509Certificate = true;
            this._certPassword = Guid.NewGuid().ToString();
            var certFilePath = _configuration["ConnectionStrings:X509Certificate:CertFile"];
            var keyFilePath = _configuration["ConnectionStrings:X509Certificate:KeyFile"];
            this._certificate = LoadCertificateFromPem(certFilePath, keyFilePath);
        }
    }
    
    protected override MongoClient CreateMongoClient(MongoUrl mongoUrl)
    {
        var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
        if (useX509Certificate)
        {
            try
            {
                mongoClientSettings.ServerApi = new ServerApi(ServerApiVersion.V1);
                mongoClientSettings.SslSettings = new SslSettings
                {
                    ClientCertificates = new List<X509Certificate>() { _certificate },
                };
                Options.MongoClientSettingsConfigurer?.Invoke(mongoClientSettings);
                return new MongoClient(mongoClientSettings);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Error while creating MongoClient with X509 certificate");
                throw;
            }
        }
    
        return base.CreateMongoClient(mongoUrl);
    }
    
    
    /// <summary>
    /// Load X509 certificate from PEM file
    /// </summary>
    private X509Certificate2 LoadCertificateFromPem(string? pemFilePath, string? keyFilePath)
    {
        if (pemFilePath is null || keyFilePath is null || !File.Exists(pemFilePath) || !File.Exists(keyFilePath))
        {
            throw new FileNotFoundException($"PEM or Key file not found at {pemFilePath} or {keyFilePath}");
        }
    
        var certificate = X509Certificate2.CreateFromPemFile(pemFilePath, keyFilePath);
        return new X509Certificate2(certificate.Export(X509ContentType.Pfx, _certPassword), _certPassword);
    }
    

    }`

    to replace in a correct way the provider use this code:

    private void ConfigureMongoX509CertificateProvider(ServiceConfigurationContext context, IConfiguration configuration) { context.Services.Replace(ServiceDescriptor.Transient( typeof(IMongoDbContextProvider<>), typeof(X509CertificateUnitOfWorkMongoDbContextProvider<>))); }

    Thanks Giuseppe

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Many Thanks Giuseppe

Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 12, 2025, 10:20