Open Closed

Extrange caching Behavior #4706


User avatar
0
jmalla.cp created
  • ABP Framework version: v6.0.1
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): Tired
  • UI Theme: LeptonX: Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX 1.0.0

I get strange behavior when running my project on my production service.

Everything starts up fine, but after a few minuts doing nothing on the web, when I run some action on the web, such as click menu option, the left hand menu disappear, and the web shows me that I'm not authorized. If I try to logout and go back in again the issue persists. I need to clean the browser cache and redis cache and then everything shows up.

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

10 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Please share all logs of your projects. AuthServer ApiHost and Web. liming.ma@volosoft.com

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The token lifetime is 1 hour by default. You can increase it by

    PreConfigure<OpenIddictServerBuilder>(builder =>
    {
        builder.SetAccessTokenLifetime(TimeSpan.FromHours(12));
    });
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    jmalla.cp created

    Hi,

    I get it, but if I log out and then log back in, the menu on the left dosen't show it. Why if I renewed the token?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can try IntrospectAccessToken in your web project. please share the logs of AuthServer ApiHost and Web again if still not working.

        <PackageReference Include="IdentityModel" Version="6.0.0" />
    
    context.Services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies", options =>
        {
            options.ExpireTimeSpan = TimeSpan.FromDays(365);
            options.IntrospectAccessToken();
        })
    
    using System;
    using IdentityModel.Client;
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authentication.OpenIdConnect;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Options;
    
    namespace MyCompanyName.MyProjectName.Web;
    
    public static class CookieAuthenticationOptionsExtensions
    {
        /// <summary>
        /// Introspect access token on validating the principal.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="oidcAuthenticationScheme"></param>
        /// <returns></returns>
        public static CookieAuthenticationOptions IntrospectAccessToken(this CookieAuthenticationOptions options, string oidcAuthenticationScheme = "oidc")
        {
            var originalHandler = options.Events.OnValidatePrincipal;
            options.Events.OnValidatePrincipal = async principalContext =>
            {
                originalHandler?.Invoke(principalContext);
    
                if (principalContext.Principal != null && principalContext.Principal.Identity != null && principalContext.Principal.Identity.IsAuthenticated)
                {
                    var accessToken = principalContext.Properties.GetTokenValue("access_token");
                    if (!accessToken.IsNullOrWhiteSpace())
                    {
                        var openIdConnectOptions = principalContext.HttpContext.RequestServices.GetRequiredService<IOptionsMonitor<OpenIdConnectOptions>>().Get(oidcAuthenticationScheme);
                        if (openIdConnectOptions.Configuration == null && openIdConnectOptions.ConfigurationManager != null)
                        {
                            openIdConnectOptions.Configuration = await openIdConnectOptions.ConfigurationManager.GetConfigurationAsync(principalContext.HttpContext.RequestAborted);
                        }
    
                        var response = await openIdConnectOptions.Backchannel.IntrospectTokenAsync(new TokenIntrospectionRequest
                        {
                            Address = openIdConnectOptions.Configuration?.IntrospectionEndpoint ?? openIdConnectOptions.Authority.EnsureEndsWith('/') + "connect/introspect",
                            ClientId = openIdConnectOptions.ClientId,
                            ClientSecret = openIdConnectOptions.ClientSecret,
                            Token = accessToken
                        });
    
                        if (response.IsActive)
                        {
                            return;
                        }
                    }
    
                    principalContext.RejectPrincipal();
                    await principalContext.HttpContext.SignOutAsync(principalContext.Scheme.Name);
                }
            };
    
            return options;
        }
    }
    
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    jmalla.cp created

    Hi,

    Sorry, but not working. I just sent you new logs

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you test if changing ApplicationConfigurationDtoCacheAbsoluteExpiration works?

    By the way change log level in all applications.

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
            Configure<AbpAspNetCoreMvcClientCacheOptions>(options =>
            {
                options.ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.Zero;
            });
    }
    
    public class Program
    {
        public async static Task<int> Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .Enrich.FromLogContext()
                .WriteTo.Async(c => c.File("Logs/logs.txt"))
                .WriteTo.Async(c => c.Console())
                .CreateLogger();
    
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    jmalla.cp created

    Hi,

    What namespace do I need, to use AbpAspNetCoreMvcClientCacheOptions?

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You are using 6.0

    Add MyMvcCachedApplicationConfigurationClient class. set AbsoluteExpirationRelativeToNow = TimeSpan.Zero

    
    using System;
    using System.Globalization;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Caching.Distributed;
    using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
    using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies;
    using Volo.Abp.AspNetCore.Mvc.Client;
    using Volo.Abp.Caching;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Threading;
    using Volo.Abp.Users;
    
    namespace MyCompanyName.MyProjectName.Web;
    
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(ICachedApplicationConfigurationClient), typeof(MyMvcCachedApplicationConfigurationClient))]
    public class MyMvcCachedApplicationConfigurationClient :  ICachedApplicationConfigurationClient, ITransientDependency
    {
        protected IHttpContextAccessor HttpContextAccessor { get; }
        protected AbpApplicationConfigurationClientProxy ApplicationConfigurationAppService { get; }
        protected ICurrentUser CurrentUser { get; }
        protected IDistributedCache<ApplicationConfigurationDto> Cache { get; }
    
        public MyMvcCachedApplicationConfigurationClient(
            IDistributedCache<ApplicationConfigurationDto> cache,
            AbpApplicationConfigurationClientProxy applicationConfigurationAppService,
            ICurrentUser currentUser,
            IHttpContextAccessor httpContextAccessor)
        {
            ApplicationConfigurationAppService = applicationConfigurationAppService;
            CurrentUser = currentUser;
            HttpContextAccessor = httpContextAccessor;
            Cache = cache;
        }
    
        public async Task<ApplicationConfigurationDto> GetAsync()
        {
            var cacheKey = CreateCacheKey();
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
            {
                return configuration;
            }
    
            configuration = await Cache.GetOrAddAsync(
                cacheKey,
                async () => await ApplicationConfigurationAppService.GetAsync(),
                () => new DistributedCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.Zero //TODO: Should be configurable.
                }
            );
    
            if (httpContext != null)
            {
                httpContext.Items[cacheKey] = configuration;
            }
    
            return configuration;
        }
    
        public ApplicationConfigurationDto Get()
        {
            var cacheKey = CreateCacheKey();
            var httpContext = HttpContextAccessor?.HttpContext;
    
            if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
            {
                return configuration;
            }
    
            return AsyncHelper.RunSync(GetAsync);
        }
    
        private string CreateCacheKey()
        {
            var userKey = CurrentUser.Id?.ToString("N") ?? "Anonymous";
            return $"ApplicationConfiguration_{userKey}_{CultureInfo.CurrentUICulture.Name}";
        }
    }
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    jmalla.cp created

    Hi,

    With your last recomendation I get this error.

    ArgumentOutOfRangeException: The relative expiration value must be positive. (Parameter 'AbsoluteExpirationRelativeToNow')
    Actual value was 00:00:00.
    
    Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions.set_AbsoluteExpirationRelativeToNow(Nullable<TimeSpan> value)
    
        Stack Query Cookies Headers Routing 
    
        ArgumentOutOfRangeException: The relative expiration value must be positive. (Parameter 'AbsoluteExpirationRelativeToNow') Actual value was 00:00:00.
            Microsoft.Extensions.Caching.Distributed.DistributedCacheEntryOptions.set_AbsoluteExpirationRelativeToNow(Nullable<TimeSpan> value)
            Cincaporc.WebApp.Web.MyMvcCachedApplicationConfigurationClient+<>c.<GetAsync>b__13_1() in MyMvcCachedApplicationConfigurationClient.cs
    
                        () => new DistributedCacheEntryOptions
    
    Volo.Abp.Caching.DistributedCache<TCacheItem, TCacheKey>.GetOrAddAsync(TCacheKey key, Func<Task<TCacheItem>> factory, Func<DistributedCacheEntryOptions> optionsFactory, Nullable<bool> hideErrors, bool considerUow, CancellationToken token)
    Cincaporc.WebApp.Web.MyMvcCachedApplicationConfigurationClient.GetAsync() in MyMvcCachedApplicationConfigurationClient.cs
    
                    configuration = await Cache.GetOrAddAsync(
    
    Volo.Abp.AspNetCore.Mvc.Client.RemoteLanguageProvider.GetLanguagesAsync()
    Microsoft.AspNetCore.RequestLocalization.DefaultAbpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync()
    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)
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi Sorry for that, Please ignore the cache.

     configuration = await ApplicationConfigurationAppService.GetAsync();
    
    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 09, 2026, 11:56
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.