Ends in:
0 DAY
16 HRS
16 MIN
23 SEC
Ends in:
0 D
16 H
16 M
23 S
Open Closed

Error after OpenIddict Migration #4588


User avatar
0

We're working on upgrading our solution though we needed to migrate from IdentityServer to OpenIddict first. We followed this guide: https://docs.abp.io/en/commercial/latest/migration-guides/openIddict-step-by-step and https://docs.abp.io/en/commercial/latest/migration-guides/openIddict-mvc#web-project-tiered-solution and after a bit of fiddling with the application URLs we're getting the following:

ComponentNotRegisteredException: The requested service 'Volo.Abp.Account.Public.Web.Pages.Account.LogoutModel' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

  • ABP Framework version: v6.0
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): Tiered/yes
  • Exception message and stack trace:
Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable<Parameter> parameters)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider+<>c__DisplayClass3_0.<CreateModelFactory>b__0(PageContext pageContext)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.CreateInstance()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResourceFilter()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in MiniProfilerMiddleware.cs
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
  • Steps to reproduce the issue:"
  • Login to the web app
  • Logout from the web app using the menu/logout

Expected: The user should be logged out Actual: This exception is shown when the user is directed to https://localhost:44357/Account/Logout

We're not using anything custom for auth, just the built-ins.


11 Answer(s)
  • User Avatar
    0
    onurpicakci created

    Hi, can you check the configurations and module dependencies in the webModule of your application? The error seems to be related to this.

  • User Avatar
    0
    [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)
    )]
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    We have an example you can check: https://github.com/abpframework/abp-samples/tree/master/Ids2OpenId

    BTW, can you share the full logs?(webapp & authserver)

  • User Avatar
    0

    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.

  • User Avatar
    0

    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();
                    });
                }
            }
        }
    
  • User Avatar
    0

    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));
            });
        }
    }
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can try to add Volo.Abp.Account.Pro.Public.Web.Impersonation package to the Web project.

    And add typeof(AbpAccountPublicWebImpersonationModule) to the Web module class.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Add AccountController to the Web project

    public class AccountController : AbpAccountImpersonationChallengeAccountController
    {
    
    }
    
    
  • User Avatar
    0

    No change.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Can you share a project that can reproduce the problem? shiwei.liang@volosoft.com I will check it. thanks.

  • User Avatar
    0

    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.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19