[maliming] said: hi
1, Add
AbpHttpClientIdentityModelWebModule
to yourApplicationBlazorModule
2, Add
AbpCachingStackExchangeRedisModule
to yourBackendHttpApiHostModule
3, Update
BackendHttpApiHostModule's ConfigureAuthentication
as below:private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) { Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "AuthServer:"; }); context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => { options.IsDynamicClaimsEnabled = true; }); }
Your Blazor and API need to enable the Redis and use the same
KeyPrefix
.Thanks.
hi I have solved the problem, thank you very much!
[maliming] said: hi
I get an error while building your project.
error NU1101: Unable to find package HQSOFT.Xspire.Backend.HttpApi.Client.
Can you try to update the
ConfigureAuthentication
method as below?private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) { context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => { options.IsDynamicClaimsEnabled = true; }); }
Thanks.
Hi
I have set up the build process to generate backend packages. Please build the Backend to produce those packages for installation into the application.
Configure the path in the package sources and try building the application again
I tried the method you suggested, but it still didn't work.
Thanks
[maliming] said: hi
Can you share a template project that reproduces the issue?
liming.ma@volosoft.com
Thanks.
I have sent the sample project to your email.
and here is configuration file for UI Application:
namespace HQSOFT.Xspire.Application.Blazor;
[DependsOn( typeof(AbpCachingStackExchangeRedisModule), typeof(AbpDistributedLockingModule), typeof(AbpAutofacModule), typeof(AbpAccountPublicBlazorWebAssemblyBundlingModule), typeof(AbpAccountPublicWebImpersonationModule), typeof(AbpAccountAdminBlazorServerModule), typeof(AbpAccountPublicBlazorServerModule), typeof(AbpIdentityProBlazorServerModule), typeof(TextTemplateManagementBlazorServerModule), typeof(AbpAuditLoggingBlazorServerModule), typeof(AbpAuditLoggingBlazorWebAssemblyBundlingModule), typeof(AbpGdprBlazorServerModule), typeof(AbpOpenIddictProBlazorServerModule), typeof(LanguageManagementBlazorServerModule), typeof(FileManagementBlazorServerModule), typeof(FileManagementBlazorWebAssemblyBundlingModule), typeof(SaasHostBlazorServerModule), typeof(SaasHostBlazorWebAssemblyBundlingModule), typeof(LeptonXThemeManagementBlazorServerModule), typeof(AbpAspNetCoreComponentsServerLeptonXThemeModule), typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule), typeof(AbpAspNetCoreMvcUiLeptonXThemeModule), typeof(AbpSwashbuckleModule), typeof(AbpAspNetCoreSerilogModule), typeof(AbpAspNetCoreMvcClientModule), typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule), typeof(AbpHttpClientWebModule), typeof(BackendHttpApiClientModule) )] public class ApplicationBlazorModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => { options.AddAssemblyResource( typeof(BackendResource), typeof(BackendDomainSharedModule).Assembly, typeof(BackendApplicationContractsModule).Assembly, typeof(ApplicationBlazorModule).Assembly ); });
PreConfigure<AbpAspNetCoreComponentsWebOptions>(options =>
{
options.IsBlazorWebApp = true;
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
if (!configuration.GetValue<bool>("App:DisablePII"))
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
Microsoft.IdentityModel.Logging.IdentityModelEventSource.LogCompleteSecurityArtifact = true;
}
// Add services to the container.
context.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
// Add DevExpress
context.Services.AddDevExpressBlazor();
ConfigureUrls(configuration);
ConfigureBundles();
ConfigureAuthentication(context, configuration);
ConfigureImpersonation(context, configuration);
ConfigureAutoMapper();
//ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureSwaggerServices(context.Services);
ConfigureCache(configuration);
ConfigureDataProtection(context, configuration, hostingEnvironment);
ConfigureDistributedLocking(context, configuration);
ConfigureBlazorise(context);
ConfigureRouter();
ConfigureMenu(configuration);
ConfigureCookieConsent(context);
ConfigureTheme();
}
private void ConfigureCookieConsent(ServiceConfigurationContext context)
{
context.Services.AddAbpCookieConsent(options =>
{
options.IsEnabled = true;
options.CookiePolicyUrl = "/CookiePolicy";
options.PrivacyPolicyUrl = "/PrivacyPolicy";
});
}
private void ConfigureTheme()
{
Configure<LeptonXThemeOptions>(options =>
{
options.DefaultStyle = LeptonXStyleNames.System;
});
Configure<LeptonXThemeBlazorOptions>(options =>
{
options.Layout = LeptonXBlazorLayouts.SideMenu;
});
}
private void ConfigureUrls(IConfiguration configuration)
{
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
});
Configure<AbpAccountLinkUserOptions>(options =>
{
options.LoginUrl = configuration["AuthServer:Authority"];
});
}
private void ConfigureBundles()
{
Configure<AbpBundlingOptions>(options =>
{
// Blazor Web App
options.Parameters.InteractiveAuto = true;
// MVC UI
options.StyleBundles.Configure(
LeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
options.ScriptBundles.Configure(
LeptonXThemeBundles.Scripts.Global,
bundle =>
{
bundle.AddFiles("/global-scripts.js");
}
);
// Blazor UI
options.StyleBundles.Configure(
BlazorLeptonXThemeBundles.Styles.Global,
bundle =>
{
bundle.AddFiles("/global-styles.css");
}
);
});
Configure<AbpBundlingOptions>(options =>
{
var globalStyles = options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global);
globalStyles.AddContributors(typeof(ApplicationStyleBundleContributor));
var globalScripts = options.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global);
globalScripts.AddContributors(typeof(ApplicationScriptBundleContributor));
options.Parameters["LeptonXTheme.Layout"] = "side-menu"; // side-menu or top-menu
});
}
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(365);
options.IntrospectAccessToken();
})
.AddAbpOpenIdConnect("oidc", options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata");;
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ClientId = configuration["AuthServer:ClientId"];
options.ClientSecret = configuration["AuthServer:ClientSecret"];
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("roles");
options.Scope.Add("email");
options.Scope.Add("phone");
options.Scope.Add("AuthServer");
});
if (configuration.GetValue<bool>("AuthServer:IsOnK8s"))
{
context.Services.Configure<OpenIdConnectOptions>("oidc", options =>
{
options.TokenValidationParameters.ValidIssuers = new[]
{
configuration["AuthServer:MetaAddress"]!.EnsureEndsWith('/'),
configuration["AuthServer:Authority"]!.EnsureEndsWith('/')
};
options.MetadataAddress = configuration["AuthServer:MetaAddress"]!.EnsureEndsWith('/') +
".well-known/openid-configuration";
var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider;
options.Events.OnRedirectToIdentityProvider = async ctx =>
{
// Intercept the redirection so the browser navigates to the right URL in your host
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/authorize";
if (previousOnRedirectToIdentityProvider != null)
{
await previousOnRedirectToIdentityProvider(ctx);
}
};
var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut;
options.Events.OnRedirectToIdentityProviderForSignOut = async ctx =>
{
// Intercept the redirection for signout so the browser navigates to the right URL in your host
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/logout";
if (previousOnRedirectToIdentityProviderForSignOut != null)
{
await previousOnRedirectToIdentityProviderForSignOut(ctx);
}
};
});
}
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureImpersonation(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.Configure<SaasHostBlazorOptions>(options =>
{
options.EnableTenantImpersonation = true;
});
context.Services.Configure<AbpIdentityProBlazorOptions>(options =>
{
options.EnableUserImpersonation = true;
});
}
/* private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment) { if (hostingEnvironment.IsDevelopment()) { Configure<AbpVirtualFileSystemOptions>(options => { options.FileSets.ReplaceEmbeddedByPhysical<ApplicationDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Application.Domain.Shared")); options.FileSets.ReplaceEmbeddedByPhysical<ApplicationApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Application.Application.Contracts")); options.FileSets.ReplaceEmbeddedByPhysical<ApplicationBlazorModule>(hostingEnvironment.ContentRootPath); }); } }*/
private void ConfigureSwaggerServices(IServiceCollection services)
{
services.AddAbpSwaggerGen(
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "AuthServer API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
}
);
}
private void ConfigureCache(IConfiguration configuration)
{
Configure<AbpDistributedCacheOptions>(options =>
{
options.KeyPrefix = "AuthServer:";
});
}
private void ConfigureDataProtection(
ServiceConfigurationContext context,
IConfiguration configuration,
IWebHostEnvironment hostingEnvironment)
{
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("AuthServer");
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!);
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "Application-Protection-Keys");
}
}
private void ConfigureDistributedLocking(
ServiceConfigurationContext context,
IConfiguration configuration)
{
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
}
private void ConfigureBlazorise(ServiceConfigurationContext context)
{
context.Services
.AddBootstrap5Providers()
.AddFontAwesomeIcons();
}
private void ConfigureMenu(IConfiguration configuration)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new ApplicationMenuContributor(configuration));
});
}
private void ConfigureRouter()
{
Configure<AbpRouterOptions>(options =>
{
options.AppAssembly = typeof(ApplicationBlazorModule).Assembly;
options.AdditionalAssemblies.Add(typeof(ApplicationBlazorClientModule).Assembly);
});
}
private void ConfigureAutoMapper()
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<ApplicationBlazorModule>();
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();
app.Use(async (ctx, next) =>
{
/* Converting to https to be able to include https URLs in `/.well-known/openid-configuration` endpoint.
* This should only be done if the request is coming outside of the cluster. */
if (ctx.Request.Headers.ContainsKey("from-ingress"))
{
ctx.Request.Scheme = "https";
}
await next();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
app.UseHsts();
}
app.UseCorrelationId();
app.UseRouting();
var configuration = context.GetConfiguration();
if (Convert.ToBoolean(configuration["AuthServer:IsOnK8s"]))
{
app.Use(async (context, next) =>
{
if (context.Request.Path.Value != null &&
context.Request.Path.Value.StartsWith("/appsettings", StringComparison.OrdinalIgnoreCase) &&
context.Request.Path.Value.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
{
// Set endpoint to null so the static files middleware will handle the request.
context.SetEndpoint(null);
}
await next(context);
});
app.UseStaticFilesForPatterns("appsettings*.json");
}
app.MapAbpStaticAssets();
app.UseAbpSecurityHeaders();
app.UseAuthentication();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseDynamicClaims();
app.UseAntiforgery();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Application API");
});
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints(builder =>
{
builder.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(builder.ServiceProvider.GetRequiredService<IOptions<AbpRouterOptions>>().Value.AdditionalAssemblies.ToArray());
});
}
}
I checked all of them and it still not login, here is configuration for backend:
namespace HQSOFT.Xspire.Backend;
[DependsOn( typeof(BackendHttpApiModule), typeof(AbpStudioClientAspNetCoreModule), typeof(AbpAspNetCoreMvcUiLeptonThemeModule), typeof(AbpAutofacModule), typeof(AbpAspNetCoreMultiTenancyModule), typeof(BackendApplicationModule), typeof(BackendEntityFrameworkCoreModule), typeof(AbpAccountPublicWebImpersonationModule), typeof(AbpAccountPublicWebOpenIddictModule), typeof(AbpSwashbuckleModule), typeof(AbpAspNetCoreSerilogModule) )] public class BackendHttpApiHostModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration();
PreConfigure<OpenIddictBuilder>(builder =>
{
builder.AddValidation(options =>
{
options.AddAudiences("AuthServer");
options.UseLocalServer();
options.UseAspNetCore();
});
});
if (!hostingEnvironment.IsDevelopment())
{
PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
{
options.AddDevelopmentEncryptionAndSigningCertificate = false;
});
PreConfigure<OpenIddictServerBuilder>(serverBuilder =>
{
serverBuilder.AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]!);
serverBuilder.SetIssuer(new Uri(configuration["AuthServer:Authority"]!));
});
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (!configuration.GetValue<bool>("App:DisablePII"))
{
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
Microsoft.IdentityModel.Logging.IdentityModelEventSource.LogCompleteSecurityArtifact = true;
}
if (!configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"))
{
Configure<OpenIddictServerAspNetCoreOptions>(options =>
{
options.DisableTransportSecurityRequirement = true;
});
Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto;
});
}
ConfigureAuthentication(context, configuration);
ConfigureUrls(configuration);
//ConfigureBundles();
ConfigureConventionalControllers();
ConfigureExternalProviders(context);
ConfigureImpersonation(context, configuration);
ConfigureHealthChecks(context);
ConfigureSwagger(context, configuration);
ConfigureVirtualFileSystem(context);
ConfigureCors(context, configuration);
//ConfigureTheme();
}
/*private void ConfigureTheme()
{
Configure<LeptonXThemeOptions>(options =>
{
options.DefaultStyle = LeptonXStyleNames.System;
});
}*/
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddAbpJwtBearer(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata");
options.Audience = "AuthServer";
});
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options =>
{
options.IsDynamicClaimsEnabled = true;
});
}
private void ConfigureUrls(IConfiguration configuration)
{
Configure<AppUrlOptions>(options =>
{
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty<string>());
});
}
/* private void ConfigureBundles() { Configure<AbpBundlingOptions>(options => { options.StyleBundles.Configure( LeptonXThemeBundles.Styles.Global, bundle => { bundle.AddFiles("/global-styles.css"); } );
options.ScriptBundles.Configure(
LeptonXThemeBundles.Scripts.Global,
bundle =>
{
bundle.AddFiles("/global-scripts.js");
}
);
});
}*/
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<BackendDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Backend.Domain.Shared"));
options.FileSets.ReplaceEmbeddedByPhysical<BackendDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Backend.Domain"));
options.FileSets.ReplaceEmbeddedByPhysical<BackendApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Backend.Application.Contracts"));
options.FileSets.ReplaceEmbeddedByPhysical<BackendApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}HQSOFT.Xspire.Backend.Application"));
});
}
}
private void ConfigureConventionalControllers()
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(BackendApplicationModule).Assembly);
});
}
private static void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAbpSwaggerGenWithOidc(
configuration["AuthServer:Authority"]!,
["AuthServer"],
[AbpSwaggerOidcFlows.AuthorizationCode],
null,
options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "AuthServer API", Version = "v1" });
options.DocInclusionPredicate((docName, description) => true);
options.CustomSchemaIds(type => type.FullName);
});
}
private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]?
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim().RemovePostFix("/"))
.ToArray() ?? Array.Empty<string>()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
}
private void ConfigureExternalProviders(ServiceConfigurationContext context)
{
context.Services.AddAuthentication()
.AddGoogle(GoogleDefaults.AuthenticationScheme, options =>
{
options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture, "picture");
})
.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";
options.ClaimActions.MapCustomJson("picture", _ => "https://graph.microsoft.com/v1.0/me/photo/$value");
options.SaveTokens = true;
})
.WithDynamicOptions<MicrosoftAccountOptions, MicrosoftAccountHandler>(
MicrosoftAccountDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ClientId);
options.WithProperty(x => x.ClientSecret, isSecret: true);
}
)
.AddTwitter(TwitterDefaults.AuthenticationScheme, options =>
{
options.ClaimActions.MapJsonKey(AbpClaimTypes.Picture, "profile_image_url_https");
options.RetrieveUserDetails = true;
})
.WithDynamicOptions<TwitterOptions, TwitterHandler>(
TwitterDefaults.AuthenticationScheme,
options =>
{
options.WithProperty(x => x.ConsumerKey);
options.WithProperty(x => x.ConsumerSecret, isSecret: true);
}
);
}
private void ConfigureImpersonation(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.Configure<AbpAccountOptions>(options =>
{
options.TenantAdminUserName = "admin";
options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation;
options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation;
});
}
private void ConfigureHealthChecks(ServiceConfigurationContext context)
{
context.Services.AddBackendHealthChecks();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
if (!env.IsDevelopment())
{
app.UseErrorPage();
}
app.UseRouting();
app.MapAbpStaticAssets();
app.UseAbpStudioLink();
app.UseAbpSecurityHeaders();
app.UseCors();
app.UseAuthentication();
app.UseAbpOpenIddictValidation();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseUnitOfWork();
app.UseDynamicClaims();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "AuthServer API");
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
});
app.UseAuditing();
app.UseAbpSerilogEnrichers();
app.UseConfiguredEndpoints();
}
}
Hi, I have separated my solution into two independent projects:
Application UI (Blazor WebApp) for handling the frontend
Backend API & AuthServer for backend logic and authentication
Both projects run successfully. When I attempt to log in from the Application UI, it redirects me correctly to the AuthServer for authentication. However, after completing the login process, it redirects back to the UI but the user is still not logged in.
It seems like the login state is not preserved or there might be a misconfiguration in the redirection or cookie/token handling.
Can someone help me identify what might be missing or misconfigured in this scenario?
Hi ABP Support Team,
I am using ABP Blazor Web App version 9.1.0 with PostgreSQL and EF Core. I want to implement the "force password change on next login" flow using ResetPasswordAsync and GeneratePasswordResetTokenAsync from IdentityUserManager. However, I always get the following error when calling these methods:
System.NotSupportedException: 'No IUserTwoFactorTokenProvider<TUser> named 'Default' is registered.'
My configuration in CoreBackendHttpApiHostModule.cs:
context.Services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<CoreBackendDbContext>() .AddDefaultTokenProviders();
I have installed Microsoft.AspNetCore.Identity.EntityFrameworkCore. My CoreBackendDbContext inherits from AbpDbContext<CoreBackendDbContext>. I do not have any custom User or Role classes, I am using the default IdentityUser and IdentityRole. I have cleaned and rebuilt the solution, but the error persists. The code that causes the error:
var result = await _userManager.ResetPasswordAsync(user, input.ChangePasswordToken, input.NewPassword);
What I have tried: Adding correct using statements. Ensuring only one call to AddIdentity<> exists. Registering DataProtectorTokenProvider<IdentityUser> manually – still doesn't work. Could you please advise what might be missing in my configuration, or if there is any ABP-specific requirement to enable the default token provider for password reset?
Thank you very much!