In our Blazor server application, we want the user's session to end if he or she does not perform any operations for a certain period of time. For this, I wrote the following codes in the program.cs file, but it did not work. While the user's password can be changed within a certain period of time in the interface, I could not find a setting related to this. How do we do it?
Here is my codes:
builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; })
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
options.SlidingExpiration = true;
});
35 Answer(s)
-
0
hi
In our Blazor server application
Is your app Tiered (MVC) or Auth Server Separated (Angular)?
-
0
My app's UI framework is Tired ( Blazor Server)
-
0
hi
What happens when you refresh the page in 10 minutes?
You can check the network panel of chrome to see the request.
-
0
Nothing changes after 10 minutes of inactivity on the platform or when the page is refreshed after 10 minutes. The user's session is in progress. We want the session to end and the user to log in again.
-
0
hi
Please share the logs of balzor server and authserver during refresh page. Thanks
liming.ma@volosoft.com
I think the login status of blazor is invalid. But the state of autherver is still valid, so the user can log in automatically.
-
0
hi
I will set
ExpireTimeSpan
and test my locally. Thanks. -
0
hi,
How did you use ExpireTimeSpan. I used it too but it didn't work. Can you help me? I need to complete this project
-
0
hi
I'm testing it now.
-
0
hi
Add the below code to your blazor server:
.AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(3); options.SlidingExpiration = true; options.Events.OnSigningIn = cookie => { cookie.Properties.IsPersistent = true; return Task.CompletedTask; }; })
Add the below code to your auth server:
context.Services.ConfigureApplicationCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(3); options.SlidingExpiration = true; options.Events.OnSigningIn = cookie => { cookie.Properties.IsPersistent = true; return Task.CompletedTask; }; });
-
0
This is how we tried. .AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(3); options.SlidingExpiration = true; options.Events.OnSigningIn = cookie => { cookie.Properties.IsPersistent = true; return Task.CompletedTask; }; }) We wrote this code in program.cs in the blazor layer. context.Services.ConfigureApplicationCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(3); options.SlidingExpiration = true; options.Events.OnSigningIn = cookie => { cookie.Properties.IsPersistent = true; return Task.CompletedTask; }; }); We wrote this code in blazormodule.cs. But maybe something went wrong. Can you share with us the sample project you are working on?
-
0
-
0
Thank you very much :) How will I include the auth server in the project? Can you help me with this? It is not included in our project
-
0
hi
Can you share your project structure screenshoot?
-
0
-
0
hi
My app's UI framework is Tired ( Blazor Server)
Your app is not tiered. : )
Please share the code of Blazor startup module.
-
0
Hi,
Sorry :) Here is my program.cs code:
using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; using Serilog.Events;
namespace IntergenLab.Blazor;
public class Program { public async static Task<int> Main(string[] args) { Log.Logger = new LoggerConfiguration() #if DEBUG .MinimumLevel.Debug() #else .MinimumLevel.Information() #endif .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) .WriteTo.Async(c => c.Console()) .CreateLogger();
try { Log.Information("Starting web host."); var builder = WebApplication.CreateBuilder(args); builder.Host .AddAppSettingsSecretsJson() .UseAutofac() .UseSerilog(); await builder.AddApplicationAsync<IntergenLabBlazorModule>(); var app = builder.Build(); await app.InitializeApplicationAsync(); await app.RunAsync(); return 0; } catch (Exception ex) { if (ex is HostAbortedException) { throw; } Log.Fatal(ex, "Host terminated unexpectedly!"); return 1; } finally { Log.CloseAndFlush(); } }
}
-
0
hi
Please share the code of
IntergenLabBlazorModule
-
0
Hi,
Here is my program.cs code:
using System; using System.IO; using System.Security.Cryptography.X509Certificates; using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Authentication.Google; using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Authentication.Twitter; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Extensions.DependencyInjection; using OpenIddict.Validation.AspNetCore; using OpenIddict.Server.AspNetCore; using IntergenLab.Blazor.Menus; using IntergenLab.EntityFrameworkCore; using IntergenLab.Localization; using IntergenLab.MultiTenancy; using Microsoft.OpenApi.Models; using Volo.Abp; using Volo.Abp.Account.Pro.Admin.Blazor.Server; using Volo.Abp.Account.Pro.Public.Blazor.Server; using Volo.Abp.Account.Public.Web; using Volo.Abp.Account.Public.Web.ExternalProviders; using Volo.Abp.Account.Public.Web.Impersonation; using Volo.Abp.Account.Web; using Volo.Abp.AspNetCore.Components.Server.LeptonXTheme; using Volo.Abp.AspNetCore.Components.Server.LeptonXTheme.Bundling; using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX; using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.AuditLogging.Blazor.Server; using Volo.Abp.Autofac; using Volo.Abp.AutoMapper; using Volo.Abp.Gdpr.Blazor.Extensions; using Volo.Abp.Gdpr.Blazor.Server; using Volo.Abp.Identity; using Volo.Abp.Identity.Pro.Blazor; using Volo.Abp.Identity.Pro.Blazor.Server; using Volo.Abp.LanguageManagement.Blazor.Server; using Volo.Abp.LeptonX.Shared; using Volo.Abp.Modularity; using Volo.Abp.OpenIddict; using Volo.Abp.OpenIddict.Pro.Blazor.Server; using Volo.Abp.Swashbuckle; using Volo.Abp.TextTemplateManagement.Blazor.Server; using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation.Urls; using Volo.Abp.VirtualFileSystem; using Volo.Saas.Host; using Volo.Saas.Host.Blazor; using Volo.Saas.Host.Blazor.Server; using Volo.Abp.BlobStoring; using Volo.Abp.BlobStoring.Database; using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.Http.Features;
namespace IntergenLab.Blazor;
[DependsOn( typeof(IntergenLabApplicationModule), typeof(IntergenLabEntityFrameworkCoreModule), typeof(IntergenLabHttpApiModule), typeof(AbpAutofacModule), typeof(AbpAspNetCoreComponentsServerLeptonXThemeModule), typeof(AbpAspNetCoreMvcUiLeptonXThemeModule), typeof(AbpSwashbuckleModule), typeof(AbpAccountPublicWebImpersonationModule), typeof(AbpAspNetCoreSerilogModule), typeof(AbpAccountPublicWebOpenIddictModule), typeof(AbpAccountPublicBlazorServerModule), typeof(AbpAccountAdminBlazorServerModule), typeof(AbpAuditLoggingBlazorServerModule), typeof(AbpIdentityProBlazorServerModule), typeof(AbpOpenIddictProBlazorServerModule), typeof(LanguageManagementBlazorServerModule), typeof(SaasHostBlazorServerModule), typeof(TextTemplateManagementBlazorServerModule), typeof(AbpGdprBlazorServerModule) )] public class IntergenLabBlazorModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration();
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => { options.AddAssemblyResource( typeof(IntergenLabResource), typeof(IntergenLabDomainModule).Assembly, typeof(IntergenLabDomainSharedModule).Assembly, typeof(IntergenLabApplicationModule).Assembly, typeof(IntergenLabApplicationContractsModule).Assembly, typeof(IntergenLabBlazorModule).Assembly ); }); // Yeni Eklendi PreConfigure<OpenIddictServerAspNetCoreBuilder>(configure => { configure.DisableTransportSecurityRequirement(); }); PreConfigure<OpenIddictBuilder>(builder => { builder.AddValidation(options => { options.AddAudiences("IntergenLab"); options.UseLocalServer(); options.UseAspNetCore(); }); }); if (!hostingEnvironment.IsDevelopment()) { PreConfigure<AbpOpenIddictAspNetCoreOptions>(options => { options.AddDevelopmentEncryptionAndSigningCertificate = false; }); PreConfigure<OpenIddictServerBuilder>(builder => { builder.UseAspNetCore().EnableTokenEndpointPassthrough().DisableTransportSecurityRequirement(); builder.AddEphemeralEncryptionKey(); builder.AddEphemeralSigningKey(); //builder.AddSigningCertificate(GetSigningCertificate(hostingEnvironment, configuration)); //builder.AddEncryptionCertificate(GetSigningCertificate(hostingEnvironment, 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; } // Yeni Eklendi Configure<OpenIddictServerAspNetCoreBuilder>(configure => { configure.DisableTransportSecurityRequirement(); }); Configure<OpenIddictServerBuilder>(builder => { builder.UseAspNetCore().EnableTokenEndpointPassthrough().DisableTransportSecurityRequirement(); }); if (!Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"])) { Configure<OpenIddictServerAspNetCoreOptions>(options => { options.DisableTransportSecurityRequirement = true; }); } //Dosya yüklemesi için ayarlar Configure<HubOptions>(options => { options.DisableImplicitFromServicesParameters = true; }); Configure<AbpBlobStoringOptions>(options => { options.Containers.ConfigureDefault(container => { container.UseDatabase(); }); }); context.Services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = int.MaxValue; // Maksimum dosya boyutunu sınırsız olarak ayarlayın }); ConfigureAuthentication(context); ConfigureUrls(configuration); ConfigureBundles(); ConfigureImpersonation(context, configuration); ConfigureAutoMapper(); ConfigureVirtualFileSystem(hostingEnvironment); ConfigureSwaggerServices(context.Services); ConfigureExternalProviders(context, configuration); ConfigureAutoApiControllers(); ConfigureBlazorise(context); ConfigureRouter(context); ConfigureMenu(context); 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; }); } private void ConfigureAuthentication(ServiceConfigurationContext context) { context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); } 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 => { // MVC UI options.StyleBundles.Configure( LeptonXThemeBundles.Styles.Global, bundle => { bundle.AddFiles("/global-styles.css"); } ); // Blazor UI options.StyleBundles.Configure( BlazorLeptonXThemeBundles.Styles.Global, bundle => { bundle.AddFiles("/blazor-global-styles.css"); //You can remove the following line if you don't use Blazor CSS isolation for components bundle.AddFiles("/IntergenLab.Blazor.styles.css"); } ); }); } private void ConfigureImpersonation(ServiceConfigurationContext context, IConfiguration configuration) { context.Services.Configure<SaasHostBlazorOptions>(options => { options.EnableTenantImpersonation = true; }); context.Services.Configure<AbpIdentityProBlazorOptions>(options => { options.EnableUserImpersonation = true; }); context.Services.Configure<AbpAccountOptions>(options => { options.TenantAdminUserName = "admin"; options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation; options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation; }); } private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment) { if (hostingEnvironment.IsDevelopment()) { Configure<AbpVirtualFileSystemOptions>(options => { options.FileSets.ReplaceEmbeddedByPhysical<IntergenLabDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}IntergenLab.Domain.Shared")); options.FileSets.ReplaceEmbeddedByPhysical<IntergenLabDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}IntergenLab.Domain")); options.FileSets.ReplaceEmbeddedByPhysical<IntergenLabApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}IntergenLab.Application.Contracts")); options.FileSets.ReplaceEmbeddedByPhysical<IntergenLabApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}IntergenLab.Application")); options.FileSets.ReplaceEmbeddedByPhysical<IntergenLabBlazorModule>(hostingEnvironment.ContentRootPath); }); } } private void ConfigureSwaggerServices(IServiceCollection services) { services.AddAbpSwaggerGen( options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "IntergenLab API", Version = "v1" }); options.DocInclusionPredicate((docName, description) => true); options.CustomSchemaIds(type => type.FullName); } ); } private void ConfigureExternalProviders(ServiceConfigurationContext context, IConfiguration configuration) { 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); } ); } private void ConfigureBlazorise(ServiceConfigurationContext context) { context.Services .AddBootstrap5Providers() .AddFontAwesomeIcons(); } private void ConfigureMenu(ServiceConfigurationContext context) { Configure<AbpNavigationOptions>(options => { options.MenuContributors.Add(new IntergenLabMenuContributor()); }); } private void ConfigureRouter(ServiceConfigurationContext context) { Configure<AbpRouterOptions>(options => { options.AppAssembly = typeof(IntergenLabBlazorModule).Assembly; }); } private void ConfigureAutoApiControllers() { Configure<AbpAspNetCoreMvcOptions>(options => { options.ConventionalControllers.Create(typeof(IntergenLabApplicationModule).Assembly); }); } private void ConfigureAutoMapper() { Configure<AbpAutoMapperOptions>(options => { options.AddMaps<IntergenLabBlazorModule>(); }); } private X509Certificate2 GetSigningCertificate(IWebHostEnvironment hostingEnv, IConfiguration configuration) { var fileName = "authserver.pfx"; var passPhrase = "2D7AA457-5D33-48D6-936F-C48E5EF468ED"; var file = Path.Combine(hostingEnv.ContentRootPath, fileName); if (!File.Exists(file)) { throw new FileNotFoundException($"Signing Certificate couldn't found: {file}"); } return new X509Certificate2(file, passPhrase); } public override void OnApplicationInitialization(ApplicationInitializationContext context) { var env = context.GetEnvironment(); var app = context.GetApplicationBuilder(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseAbpRequestLocalization(); if (!env.IsDevelopment()) { app.UseErrorPage(); app.UseHsts(); } app.UseCorrelationId(); app.UseAbpSecurityHeaders(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAbpOpenIddictValidation(); if (MultiTenancyConsts.IsEnabled) { app.UseMultiTenancy(); } app.UseUnitOfWork(); app.UseAuthorization(); app.UseSwagger(); app.UseAbpSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "IntergenLab API"); }); app.UseAuditing(); app.UseAbpSerilogEnrichers(); app.UseConfiguredEndpoints(); }
}
-
0
hi
Remove your previous code
builder.Services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(10); options.SlidingExpiration = true; });
add the new below:
private void ConfigureExternalProviders(ServiceConfigurationContext context, IConfiguration configuration) { context.Services.ConfigureApplicationCookie(options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(3); options.SlidingExpiration = true; options.Events.OnSigningIn = cookie => { cookie.Properties.IsPersistent = true; return Task.CompletedTask; }; }); context.Services.AddAuthentication() .AddGoogle(GoogleDefaults.AuthenticationScheme, _ => { }) .WithDynamicOptions<GoogleOptions, GoogleHandler>( ....
-
0
Hi,
It would work, but will this only happen when I refresh the page?
-
0
It needs to be refreshed or click on other menus to navigate.
-
0
It happens when I refresh it, but it doesn't happen when I click on another menu.
-
0
Cookies will expire after 3 minutes. So
click on another menu
also will work.Can you share an online URL?
-
0
Unfortunately, I cannot publish my project. But, we can set an online meeting. It would be great for me. If you have time, please help me.
-
0
hi
Can you share the logs when you click on another menu after 3 minutes?
Set the log level to Debug.
public class Program { public async static Task<int> Main(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Async(c => c.File("Logs/logs.txt")) .WriteTo.Async(c => c.Console()) .CreateLogger();