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
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;
}
}
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
No change, exactly the same behavior. the menu doesn't appear without a refresh
Hi, the custom razor geerate an routes are ambiguous problem. here the log:
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: The following routes are ambiguous: 'authentication/{action}' in 'IBLTermocasa.Blazor.Pages.CustomAuthentication' 'authentication/{action}' in 'Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme.Pages.Authentication'
System.InvalidOperationException: The following routes are ambiguous: 'authentication/{action}' in 'IBLTermocasa.Blazor.Pages.CustomAuthentication' 'authentication/{action}' in 'Volo.Abp.AspNetCore.Components.WebAssembly.LeptonTheme.Pages.Authentication'
at Microsoft.AspNetCore.Components.RouteTableFactory.DetectAmbiguousRoutes(TreeRouteBuilder builder)
at Microsoft.AspNetCore.Components.RouteTableFactory.Create(Dictionary2 templatesByHandler, IServiceProvider serviceProvider) at Microsoft.AspNetCore.Components.RouteTableFactory.Create(List
1 componentTypes, IServiceProvider serviceProvider)
at Microsoft.AspNetCore.Components.RouteTableFactory.Create(RouteKey routeKey, IServiceProvider serviceProvider)
at Microsoft.AspNetCore.Components.Routing.Router.RefreshRouteTable()
at Microsoft.AspNetCore.Components.Routing.Router.Refresh(Boolean isNavigationIntercepted)
at Microsoft.AspNetCore.Components.Routing.Router.RunOnNavigateAsync(String path, Boolean isNavigationIntercepted)
at Microsoft.AspNetCore.Components.Routing.Router.<>c__DisplayClass76_0.<RunOnNavigateAsync>b__1(RenderTreeBuilder builder)
i have a static web app on azure for UI a Web App for the api a Web App for the AuthServer
here the zip archive of the logs https://we.tl/t-dgwiOnOiag (expire in 3 days)
Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, and please first use the search on the homepage. Provide us with the following info:
Good morning, I deployed an ABP solution as indicated. The theme used is Lepton (Standard Left SIde Menu) The solution is up and run but when I log in, the menu is empty (only Home) to see the menu I am forced to perform a refresh. I read that many have had this problem but it is not clear to me if it has been solved and how it was solved. Can you help me? in this way I cannot present it to the customer and it is creating delays on the project deadlines
Best Regards Giuseppe