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;
}
}
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(List1 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)