-
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)
-
0
hi
Can you connect your MongoDB in another app/code?
Do you have any example code of
authMechanism=MONGODB-X509
?Thanks.
-
0
Yes
follow a console app that works fine whith the same clusterusing 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; } }
-
0
hi
You can override the
UnitOfWorkMongoDbContextProvider's CreateMongoClient
method to change the code of creatingMongoClient
.Add
YourUnitOfWorkMongoDbContextProvider : UnitOfWorkMongoDbContextProvider
Then replace it in DI.
context.Services.TryAddTransient( typeof(IMongoDbContextProvider<>), typeof(UnitOfWorkMongoDbContextProvider<>) );
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);
-
0
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 : UnitOfWorkMongoDbContextProvider
where TMongoDbContext : IAbpMongoDbContext
{
private readonly IConfiguration _configuration;
private X509Certificate2 _certificate;
private String _certPassword;
private bool useX509Certificate = false;public X509CertificateUnitOfWorkMongoDbContextProvider(IUnitOfWorkManager unitOfWorkManager, IConnectionStringResolver connectionStringResolver, ICancellationTokenProvider cancellationTokenProvider, ICurrentTenant currentTenant, IOptions 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() { _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); } ///
/// Load X509 certificate from PEM file /// 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 -
0
Many Thanks Giuseppe