Azure 应用服务中的 RavenDB 云证书问题

问题描述

net5.0 ASP.NET Core 应用部署在 Azure 应用服务上。它使用 https://a.free.xxxx.ravendb.cloud 和证书。证书在我的本地环境中正确加载。它给了我下面的错误;但是,证书也会添加到 Azure 门户 - TLS/SSL 设置中 .

Unhandled exception. system.invalidOperationException: The supplied CN=free.transfocus certificate contains no private key. Constructing the certificate with the 'X509KeyStorageFlags.MachineKeySet' flag may solve this problem.
   at Raven.Client.Documents.DocumentStore.Initialize() in C:\Builds\RavendB-Stable-5.1\51016\src\Raven.Client\Documents\DocumentStore.cs:line 222
   at Raven.DependencyInjection.RavenoptionsSetup.GetDocumentStore(Action`1 configureDbStore)
   at Raven.DependencyInjection.ServiceCollectionExtensions.<>c.<AddRavendbDocStore>b__1_0(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite,RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite,TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite,RuntimeResolverContext context,ServiceProviderEnginescope serviceProviderEngine,RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite,RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite,TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite,ServiceProviderEnginescope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__displayClass1_0.<RealizeService>b__0(ServiceProviderEnginescope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType,ServiceProviderEnginescope serviceProviderEnginescope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEnginescope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetrequiredService(IServiceProvider provider,Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetrequiredService[T](IServiceProvider provider)
   at Transfocus.Middleware.Program.Main(String[] args) in D:\a\1\s\Transfocus.Middleware\Transfocus.Middleware\Program.cs:line 26

程序.cs

                using (var scope = host.Services.CreateScope())
                {
                    var services = scope.ServiceProvider;
                    var store = services.GetrequiredService<IDocumentStore>();
                    var expiration = TimeSpan.FromDays(90);
                    var errorExpiration = TimeSpan.FromDays(180);

                    Log.Logger = new LoggerConfiguration()
                        .Enrich.FromLogContext()
                        .Enrich.With()
                        .MinimumLevel.information()
                        .MinimumLevel.Override("Microsoft",LogEventLevel.Warning)
                        .MinimumLevel.Override("System",LogEventLevel.Warning)
                        .Filter.ByExcluding(c => c.Properties.Any(p => p.Value.ToString().ToLower().Contains("hangfire")))
                        .Filter.ByExcluding(c => c.Properties.Any(p => p.Value.ToString().ToLower().Contains(".ico")) || c.Properties.Any(p => p.Value.ToString().ToLower().Contains(".png")) || c.Properties.Any(p => p.Value.ToString().ToLower().Contains(".jpg")) )
                        .Writeto.RavendB(store,expiration: expiration,errorExpiration: errorExpiration)
                        .CreateLogger();
                }

我的创业班如下

            var dbConfig = Configuration.GetSection("Database").Get<AppSettings.Database>();

            var store = new DocumentStore
            {
                Urls = dbConfig.Urls,Database = dbConfig.DatabaseName
            };

            store.Conventions.USEOptimisticConcurrency = true;

            if (!string.IsNullOrWhiteSpace(dbConfig.CertPath))
                store.Certificate = new X509Certificate2(dbConfig.CertPath,dbConfig.CertPass,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

            store.Initialize();

            services.AddSingleton<IDocumentStore>(store);
            
            IndexCreation.CreateIndexes(typeof(Startup).Assembly,store);

            services.AddScoped<IAsyncDocumentSession>(sp => sp.GetService<IDocumentStore>()?.OpenAsyncSession());
            services.AddScoped<IDocumentSession>(sp => sp.GetService<IDocumentStore>()?.OpenSession());

解决方法

感谢 bartonjs 的回答,它可能对您有用。

What is the impact of the PersistKeySet-StorageFlag when importing a Certificate in C#

参考链接:

1. Install a PFX file by using X509Certificate from a standard .NET application

2. Add support for opening a PFX with an ephemeral key #17166