Trying to create the sample issue here: https://github.com/kfrancis/net8-maui-autofac-repro
MauiApp1 is just a simple maui app, that was net7.0 with autofac (not abp) and was working. Then upgraded to net8 preview 6 and it still works.
MauiApp2 is the same, but I suspect the issue comes into play with abp autofac so I'm trying to prepare a simple example of that.
Just in case others find this thread, the issue for us was that we still had some packages from before our Lepton to LeptonX migration - Volo.Abp.LeptonTheme.*
. Once we removed those six packages, it started working normally.
No change.
Here's the web module def:
[DependsOn(
typeof(CabMDHttpApiModule),
typeof(CabMDHttpApiClientModule),
typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule),
typeof(AbpAspNetCoreMvcClientModule),
typeof(AbpAutofacModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpFeatureManagementWebModule),
typeof(AbpAccountAdminWebModule),
typeof(AbpHttpClientIdentityModelWebModule),
typeof(AbpIdentityWebModule),
typeof(AbpAuditLoggingWebModule),
typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
typeof(SaasHostWebModule),
typeof(AbpOpenIddictProWebModule),
typeof(LanguageManagementWebModule),
typeof(TextTemplateManagementWebModule),
typeof(AbpSwashbuckleModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpPaymentPayuWebModule),
typeof(AbpPaymentTwoCheckoutWebModule),
typeof(AbpPaymentWebModule),
typeof(FileManagementWebModule),
typeof(DocsWebModule),
typeof(CabMDReportingModule),
typeof(CmsKitProWebModule),
typeof(AbpBlobStoringModule),
typeof(AbpTextTemplatingScribanModule)
)]
public class CabMDWebModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
ConfigureBundles();
ConfigurePages();
ConfigureCache();
ConfigureRedis(context, configuration, hostingEnvironment);
ConfigureUrls(configuration);
ConfigureAuthentication(context, configuration);
ConfigureAutoMapper();
ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureNavigationServices(configuration);
ConfigureSwaggerServices(context.Services);
ConfigureMultiTenancy();
ConfigureBackgroundJobs(context, configuration);
ConfigurePayment();
ConfigureKendo(context.Services);
ConfigureReporting(context, configuration);
ConfigurePwnedPasswords(context.Services);
ConfigureMiniProfiler(configuration, context.Services);
ConfigureJsonSerialization();
ConfigureBlobStorage();
ConfigureLayoutChanges(configuration);
//ConfigureHealthChecks(context, configuration);
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
}
app.UseCors("TelerikReportingCorsPolicy");
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseAuthorization();
if (bool.Parse(context.GetConfiguration()["App:EnableMiniProfiler"]))
{
app.UseMiniProfiler();
}
if (BackgroundJobConsts.IsEnabled)
{
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
});
}
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "CabMD API");
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(
typeof(CabMDResource),
typeof(CabMDDomainSharedModule).Assembly,
typeof(CabMDApplicationContractsModule).Assembly,
typeof(CabMDWebModule).Assembly
);
});
}
private static void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
})
.AddAbpOpenIdConnect("oidc", options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); ;
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ClientId = configuration["AuthServer:ClientId"];
options.ClientSecret = configuration["AuthServer:ClientSecret"];
options.UsePkce = true; // Add this line
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("roles");
options.Scope.Add("email");
options.Scope.Add("phone");
options.Scope.Add("CabMD");
});
}
private static void ConfigureHealthChecks(ServiceConfigurationContext context, IConfiguration configuration)
{
if (configuration.GetValue("HealthChecks:HealthChecksEnabled", false))
{
context.Services.AddCabHealthChecks(configuration.GetConnectionString("Default"));
}
}
private static void ConfigureKendo(IServiceCollection services)
{
services.AddKendo();
}
private static void ConfigureMiniProfiler(IConfiguration configuration, IServiceCollection services)
{
if (configuration.GetValue("App:EnableMiniProfiler", false))
{
services.AddMiniProfiler(options =>
{
options.RouteBasePath = "/mp";
options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.VerboseSqlServerFormatter();
options.IgnoredPaths.Add("/elmah");
options.IgnoredPaths.Add(".less");
options.TrackConnectionOpenClose = false;
options.PopupShowTimeWithChildren = true;
options.Storage = new RedisStorage(configuration["Redis:Configuration"]);
}).AddEntityFramework();
}
}
/// <summary>
/// Adds the PwnedPasswords client in DI so we can check during user registration
/// </summary>
/// <param name="services"></param>
private static void ConfigurePwnedPasswords(IServiceCollection services)
{
// see: https://blog.elmah.io/avoid-password-reuse-with-pwned-passwords-and-asp-net-core/
services.AddPwnedPasswordHttpClient(minimumFrequencyToConsiderPwned: 1)
.AddTransientHttpErrorPolicy(p => p.RetryAsync(3))
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(2)));
}
private static void ConfigureRedis(
ServiceConfigurationContext context,
IConfiguration configuration,
IWebHostEnvironment hostingEnvironment)
{
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("CabMD");
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "CabMD-Protection-Keys");
}
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer
.Connect(configuration["Redis:Configuration"]);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
private static void ConfigureReporting(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
context.Services.AddScoped<IReportSourceResolver, CabMDReportSourceResolver>();
context.Services.AddSingleton<IReportServiceConfiguration>(sp =>
new ReportServiceConfiguration
{
ReportingEngineConfiguration = configuration,
HostAppId = "ReportingCore3App",
Storage = new FileStorage(),
ReportSourceResolver = sp.GetRequiredService<IReportSourceResolver>()
});
context.Services.AddCors(o => o.AddPolicy("TelerikReportingCorsPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
context.Services.AddControllers().AddNewtonsoftJson(opt =>
{
opt.SerializerSettings.ContractResolver = new ApiHeaderJsonContractResolver(new ApiHeaderJsonNamingStrategyOptions
{
DefaultStrategy = new PascalCaseNamingStrategy(),
HeaderName = "json-naming-strategy",
HttpContextAccessorProvider = context.Services.BuildServiceProvider().GetService<IHttpContextAccessor>,
NamingStrategies = new Dictionary<string, NamingStrategy>
{
{"camelcase", new CamelCaseNamingStrategy() },
{"snakecase", new SnakeCaseNamingStrategy() },
{"pascalcase", new PascalCaseNamingStrategy() }
}
}, context.Services.BuildServiceProvider().GetService<IMemoryCache>);
}).AddJsonOptions(options =>
{
});
context.Services.AddRazorPages().AddNewtonsoftJson();
}
private static void ConfigureSwaggerServices(IServiceCollection services)
{
services.AddSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "CabMD API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
}
);
}
private void ConfigureAutoMapper()
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<CabMDWebModule>();
});
}
private void ConfigureBackgroundJobs(ServiceConfigurationContext context, IConfiguration configuration)
{
Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = BackgroundJobConsts.IsEnabled);
Configure<AbpBackgroundWorkerOptions>(options => options.IsEnabled = BackgroundJobConsts.IsEnabled);
if (BackgroundJobConsts.IsEnabled)
{
context.Services.AddHangfire(config =>
{
config.UseSqlServerStorage(configuration.GetConnectionString("Default"));
});
context.Services.AddHangfireServer();
}
}
private void ConfigureBlobStorage()
{
Configure<AbpBlobStoringOptions>(options =>
{
options.Containers.ConfigureDefault(container =>
{
container.UseDatabase();
});
});
}
private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
LeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
}
private void ConfigureCache()
{
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "CabMD:";
});
}
private void ConfigureJsonSerialization()
{
Configure<AbpJsonOptions>(options =>
{
//options.UseHybridSerializer = false;
});
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
////options.JsonSerializerOptions.Converters.Add(new JsonNonStringKeyDictionaryConverterFactory());
//options.JsonSerializerOptions.Converters.Add(new DiagnosticCodes.Diagnostic_Code.Diagnostic_CodeSystemTextJsonConverter());
//options.JsonSerializerOptions.Converters.Add(new MasterNumbers.Master_Number.Master_NumberSystemTextJsonConverter());
//options.JsonSerializerOptions.Converters.Add(new CabMD.Patients.Province_Code.Province_CodeSystemTextJsonConverter());
CabMDJsonSerializationOptions.SetConverters(options.JsonSerializerOptions);
});
//Configure<AbpNewtonsoftJsonSerializerOptions>(options =>
//{
// options.Converters.Add<AbpJsonIsoDateTimeConverter>();
//});
}
private void ConfigureLayoutChanges(IConfiguration configuration)
{
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(LeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddContributors(typeof(KendoStyleContributor));
});
options
.StyleBundles
.Get(StandardBundles.Styles.Global)
.Contributors.Remove<FontAwesomeStyleContributor>(); // Do this so we can use pro kit
});
Configure<AbpLayoutHookOptions>(options =>
{
options.Add(
LayoutHooks.Head.Last, //The hook name
typeof(KendoViewComponent) //The component to add
);
options.Add(LayoutHooks.Body.Last, typeof(KendoDeferredViewComponent));
options.Add(
LayoutHooks.Head.Last, //The hook name
typeof(FontAwesomeViewComponent) // Add the pro kit
);
if (configuration.GetValue<bool>("Intercom:Enabled", false))
{
options.Add(
LayoutHooks.Head.First,
typeof(IntercomViewComponent));
}
if (configuration.GetValue<bool>("App:EnableMiniProfiler", false))
{
options.Add(
LayoutHooks.Body.Last,
typeof(MiniProfilerViewComponent));
}
});
}
private void ConfigureMultiTenancy()
{
Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = MultiTenancyConsts.IsEnabled; });
}
private void ConfigureNavigationServices(IConfiguration configuration)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new CabMDMenuContributor(configuration));
});
Configure<AbpToolbarOptions>(options =>
{
options.Contributors.Add(new CabMDToolbarContributor());
});
}
private void ConfigurePages()
{
Configure<RazorPagesOptions>(options =>
{
options.Conventions.AuthorizePage("/HostDashboard", CabMDPermissions.Dashboard.Host);
options.Conventions.AuthorizePage("/TenantDashboard", CabMDPermissions.Dashboard.Tenant);
options.Conventions.AuthorizePage("/Plans/Index", CabMDPermissions.Plans.Default);
options.Conventions.AuthorizePage("/CareProviders/Index", CabMDPermissions.CareProviders.Default);
options.Conventions.AuthorizePage("/MasterNumbers/Index", CabMDPermissions.MasterNumbers.Default);
options.Conventions.AuthorizePage("/DiagnosticCodes/Index", CabMDPermissions.DiagnosticCodes.Default);
options.Conventions.AuthorizePage("/Services/Index", CabMDPermissions.Services.Default);
});
Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("claimstate", typeof(ClaimStateConstraint));
options.ConstraintMap.Add("patientid", typeof(PatientIdConstraint));
});
}
}
Here's the auth module def:
DependsOn(
typeof(AbpAutofacModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpAccountPublicWebOpenIddictModule),
typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
typeof(AbpAccountPublicApplicationModule),
typeof(AbpDistributedLockingModule),
typeof(CabMDEntityFrameworkCoreModule)
)]
public class CabMDAuthServerModule : AbpModule
{
private static X509Certificate2 GetSigningCertificate(IConfiguration configuration)
{
// try thumbprint first, most secure
// Note: You need to make sure WEBSITE_LOAD_CERTIFICATES={thumbprint} is on the Azure settings or
// the cert won't be found. See: https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code
var certThumbprint = configuration.GetValue<string>("SigningCertificate:Thumbprint") ?? string.Empty;
if (!string.IsNullOrEmpty(configuration.GetValue<string>("SigningCertificate:Thumbprint")))
{
using var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
var validOnly = false;
certStore.Open(OpenFlags.ReadOnly);
var certCollection = certStore.Certificates.Find(
X509FindType.FindByThumbprint,
certThumbprint,
validOnly);
// Get the first cert with the thumbprint
var cert = certCollection.OfType<X509Certificate2>().FirstOrDefault();
if (cert is null)
throw new Exception($"Certificate with thumbprint {certThumbprint} was not found");
// Use certificate
return cert;
}
else
{
// try a physical file as fallback, less secure as we need to provide password and the file is static
var certPath = configuration.GetValue<string>("SigningCertificate:Path");
if (!string.IsNullOrEmpty(certPath) && File.Exists(certPath))
{
return new X509Certificate2(certPath, configuration.GetValue<string>("SigningCertificate:Password"));
}
else
{
throw new Exception($"Certificate with SigningCertificate:Path '{certPath}' was not found");
}
}
}
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
options.AddAudiences("CabMD");
options.UseLocalServer();
options.UseAspNetCore();
});
});
if (!hostingEnvironment.IsDevelopment())
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(builder =>
{
builder.AddSigningCertificate(GetSigningCertificate(configuration));
builder.AddEncryptionCertificate(GetSigningCertificate(configuration));
builder.SetIssuer(new Uri(configuration["AuthServer:Authority"]));
});
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
if (!Convert.ToBoolean(configuration["App:DisablePII"]))
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
}
if (!Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]))
{
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
}
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<CabMDResource>()
.AddBaseTypes(
typeof(AbpUiResource)
);
});
Configure<AbpBundlingOptions>(options =>
{
options.StyleBundles.Configure(
LeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
Configure<AbpAuditingOptions>(options =>
{
//options.IsEnabledForGetRequests = true;
options.ApplicationName = "AuthServer";
});
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<CabMDDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}CabMD.Domain.Shared", Path.DirectorySeparatorChar)));
options.FileSets.ReplaceEmbeddedByPhysical<CabMDDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}CabMD.Domain", Path.DirectorySeparatorChar)));
});
}
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
});
Configure<AbpBackgroundJobOptions>(options =>
{
options.IsJobExecutionEnabled = false;
});
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "CabMD:";
});
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("CabMD");
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "CabMD-Protection-Keys");
}
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer
.Connect(configuration["Redis:Configuration"]);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
context.Services.AddAuthentication()
.AddGoogle(GoogleDefaults.AuthenticationScheme, _ => { })
.WithDynamicOptions<GoogleOptions, GoogleHandler>(
GoogleDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ClientId);
options.WithProperty(x => x.ClientSecret, isSecret: true);
}
)
.AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options =>
{
//Personal Microsoft accounts as an example.
options.AuthorizationEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
options.TokenEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
})
.WithDynamicOptions<MicrosoftAccountOptions, MicrosoftAccountHandler>(
MicrosoftAccountDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ClientId);
options.WithProperty(x => x.ClientSecret, isSecret: true);
}
)
.AddTwitter(TwitterDefaults.AuthenticationScheme, options => options.RetrieveUserDetails = true)
.WithDynamicOptions<TwitterOptions, TwitterHandler>(
TwitterDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ConsumerKey);
options.WithProperty(x => x.ConsumerSecret, isSecret: true);
}
);
context.Services.Configure<AbpAccountOptions>(options =>
{
options.TenantAdminUserName = "admin";
options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation;
options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation;
});
Configure<LeptonXThemeOptions>(options =>
{
options.DefaultStyle = LeptonXStyleNames.System;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
app.UseHsts();
app.UseHttpsRedirection();
}
app.UseCorrelationId();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAbpOpenIddictValidation();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseUnitOfWork();
app.UseAuthorization();
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
if (!env.IsDevelopment())
{
app.Use((httpContext, next) =>
{
httpContext.Request.Scheme = "https";
return next();
});
}
}
}
Yea, I followed the example I think along with the migration docs.
That project isn't using LeptonX, which we are.
Here are the Log files you asked for.
[DependsOn(
typeof(CabMDHttpApiModule),
typeof(CabMDHttpApiClientModule),
typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule),
typeof(AbpAspNetCoreMvcClientModule),
typeof(AbpAutofacModule),
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpFeatureManagementWebModule),
typeof(AbpAccountAdminWebModule),
typeof(AbpHttpClientIdentityModelWebModule),
typeof(AbpIdentityWebModule),
typeof(AbpAuditLoggingWebModule),
typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
typeof(SaasHostWebModule),
typeof(AbpOpenIddictProWebModule),
typeof(LanguageManagementWebModule),
typeof(TextTemplateManagementWebModule),
typeof(AbpSwashbuckleModule),
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpPaymentPayuWebModule),
typeof(AbpPaymentTwoCheckoutWebModule),
typeof(AbpPaymentWebModule),
typeof(FileManagementWebModule),
typeof(DocsWebModule),
typeof(CabMDReportingModule),
typeof(CmsKitProWebModule),
typeof(AbpBlobStoringModule),
typeof(AbpTextTemplatingScribanModule)
)]
I think the issue is with this line:
filename = Path.Combine(Directory.GetCurrentDirectory(), "tempkey.rsa");
https://github.com/abpframework/abp/blob/e3e1779de6df5d26f01cdc8e99ac9cbcb3d24d3c/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderExtensions.cs#L76
Need to use an option there, or find some way to specify filename so that the GetCurrentDirectory
isn't used in this context.
I understand that most aren't using WPF, but all of this would be relevant to WinUI/UWP as well - anything that would be deployed as a standalone app.
Working on something here: https://github.com/kfrancis/abp-wpf