Open Closed

Hangfire Job "Unauthorized BT! IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '21.07.2025 07:26:48', Current time (UTC): '21.07.2025 08:03:19'." #9646


User avatar
0
cetin.sahin created

We're using Hangfire for recurring and background job management. However, we're receiving the following error. We added the following packages to the API host project from previous support tickets. Our ABP version is 9.1.0.

Eror detail Unauthorized BT! IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '21.07.2025 07:26:48', Current time (UTC): '21.07.2025 08:03:19

cs
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.12.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.12.1" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.12.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.1" />
</ItemGroup>

9 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • The error "IDX10223: Lifetime validation failed. The token is expired." indicates that the JWT access token used by your Hangfire job is expired at the time of execution. This is a common issue when background jobs are scheduled to run after the token's expiration, especially in distributed or tiered ABP applications.

    • To resolve this, you should ensure that your Hangfire jobs acquire a fresh access token before making authorized API calls. Do not cache or reuse tokens for long-running or recurring jobs.

    • In microservice or tiered ABP setups, the recommended approach is to use the client credentials flow to programmatically request a new token for each job execution. This ensures the token is always valid.

    • If you are using ABP's built-in remote service proxies, configure them to use the client credentials flow and set up the necessary client in your IdentityServer/OpenIddict configuration.

    • Avoid using user tokens for background jobs, as they will expire and cannot be refreshed without user interaction.

    • If you are using distributed cache for tokens, ensure the cache expiration is not longer than the token's lifetime.

    This approach aligns with common ABP conventions, but specific official documentation for this exact scenario is not available.


    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    cetin.sahin created

    This answer cannot resolve my problem

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Why does your Hangfire need to use a JWT token?

    Can you share some code?

    Thanks.

  • User Avatar
    0
    cetin.sahin created

    We don't use JWT tokens in the job, but it gives an error.

    
    namespace EnzimWeb._Jobs
    {
        public class EnzimOnlineVizitBransListesiWorker : HangfireBackgroundWorkerBase
        {
    
            private readonly IBackgroundJobManager _backgroundJobManager;
    
            private readonly IMedicanaCMSApiClientService _CMSclient;
    
            private readonly IRandevuServiceClient _randevuWS;
            private readonly Microsoft.Extensions.Configuration.IConfiguration _configuration;
            private readonly OnlineVizitBranslarManager _onlineVizitBranslarManager;
            protected IOnlineVizitBranslarRepository _onlineVizitBranslarRepository;
            protected ILanguageTextRepository _languageRepository;
            protected IOnlineVizitDoktorRepository _onlineVizitDoktorRepository;
    
            private int timeInterval = 30;
            private int controlRange = 30;
            public EnzimOnlineVizitBransListesiWorker(IBackgroundJobManager backgroundJobManager,
                                             IMedicanaCMSApiClientService CMSclient,
                                              IRandevuServiceClient randevuWS,
                                              Microsoft.Extensions.Configuration.IConfiguration configuration,
                                              OnlineVizitBranslarManager onlineVizitBranslarManager,
                                              IOnlineVizitBranslarRepository onlineVizitBranslarRepository,
                                              ILanguageTextRepository languageRepository,
                                              IOnlineVizitDoktorRepository onlineVizitDoktorRepository
                                              )
            {
                RecurringJobId = nameof(EnzimOnlineVizitBransListesiWorker);
                CronExpression = $"*/{timeInterval} * * * *";//Cron.Minutely nin dakika verilebileni obselete. yerine methodu da anlamadım
    
    
                _CMSclient = CMSclient;
                _randevuWS = randevuWS;
    
                _configuration = configuration;
                _onlineVizitBranslarManager = onlineVizitBranslarManager;
                _backgroundJobManager = backgroundJobManager;
                _onlineVizitBranslarRepository = onlineVizitBranslarRepository;
                _languageRepository = languageRepository;
                _onlineVizitDoktorRepository = onlineVizitDoktorRepository;
    
    
            }
    
            public override async Task DoWorkAsync(CancellationToken cancellationToken = default)
            {
                bool isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
    
                //bool isDevelopment = false;
                if (!isDevelopment)
                {
    
                    ExceptionlessClient.Default
                    .CreateLog("Info")
                    .AddTags("startJob", "EnzimOnlineVizitBransListesiWorker")
                    .Submit();
    
                    try
                    {
                        #region Enzimden branslar cekilerek kaydediliyor
                        HastaneAraIstek hastaneAraIstek = new HastaneAraIstek { WSRandevuTipi = WSRandevuTipi.OnlineGorusme };
                        var hastaneler = await _randevuWS.HastaneAraAsync(hastaneAraIstek);
                        foreach (var hastane in hastaneler.Hastaneler.Where(x => x.ID != 1000 && x.ID != 6 && x.ID != 99))
                        {
                            PozisyonAraIstek input = new PozisyonAraIstek
                            {
                                HastaneId = hastane.ID,
                                WSRandevuTipi = WSRandevuTipi.OnlineGorusme
                            };
                            var pozisyonlar = await _randevuWS.PozisyonAraAsync(input);
                            if (pozisyonlar != null && pozisyonlar.Pozisyonlar.Count() > 0)
                            {
                                foreach (var pozisyon in pozisyonlar.Pozisyonlar)
                                {
    
                                    var DbBrans = await _onlineVizitBranslarRepository.GetListAsync(
                                    x => x.EnzimPozisyonId == pozisyon.ID.ToString() &
                                    x.EnzimHospitalId == hastane.ID.ToString()
                                    );
                                    if (DbBrans.Count == 0)
                                    {
                                        var Sonuc = await _onlineVizitBranslarManager.CreateAsync(true, pozisyon.Adi, pozisyon.ID.ToString(), null, null, hastane.ID.ToString()
                                            , null, "Online." + Temizle(pozisyon.Adi) + "_" + hastane.ID.ToString() + "_" + pozisyon.ID.ToString());
    
                                        var text = (await _languageRepository.GetListAsync()).FirstOrDefault(l =>
                                          l.CultureName == "tr" && l.ResourceName == "EnzimWeb" &&
                                          l.Name == Sonuc.AbpLanguageKey);
    
                                        if (text == null)
                                        {
    
                                            await _languageRepository.InsertAsync(
                                          new LanguageText(Guid.NewGuid(), "EnzimWeb", "tr", Sonuc.AbpLanguageKey, Sonuc.BransAdi, null)
                                          );
                                        }
                                        else
                                        {
    
                                            text.Value = pozisyon.Adi;
                                            await _languageRepository.UpdateAsync(text);
    
    
                                        }
    
                                        //  await _languageRepository.InsertAsync(
                                        //new LanguageText(Guid.NewGuid(), "EnzimWeb", "tr", Sonuc.AbpLanguageKey, Sonuc.BransAdi, null)
                                        //);
                                    }
                                   
                                }
                            }
    
    
                            #region randevu serviste yoksa pasife cek
                            var DbBranslar = await _onlineVizitBranslarRepository.GetListAsync(x=> x.EnzimHospitalId == hastane.ID.ToString());
                            foreach (var dbBrans in DbBranslar)
                            {
                                if(!pozisyonlar.Pozisyonlar.Any(x=>x.ID == Convert.ToInt32(dbBrans.EnzimPozisyonId)))
                                {
                                    var Update = await _onlineVizitBranslarRepository.GetAsync(dbBrans.Id);
                                    Update.RandevuAlinabilirmi = false;
                                    var Updatesonuc = await _onlineVizitBranslarRepository.UpdateAsync(Update);
                                   
                                    var DBdoktorlar = await _onlineVizitDoktorRepository.GetListAsync(
                                        x => x.EnzimHospitalId == hastane.ID.ToString() &&
                                        x.EnzimPozisyonId == dbBrans.EnzimPozisyonId.ToString()
                                        );
                                    foreach (var DBdoktor in DBdoktorlar)
                                    {
                                        DBdoktor.RandevuAlinabilirmi = false;
                                        var Updatedoktorsonuc = await _onlineVizitDoktorRepository.UpdateAsync(DBdoktor);
                                    }
                                }
                                else
                                {
                                    var Update = await _onlineVizitBranslarRepository.GetAsync(dbBrans.Id);
                                    Update.RandevuAlinabilirmi = true;
                                    var Updatesonuc = await _onlineVizitBranslarRepository.UpdateAsync(Update);
                                }
                            }
                            #endregion
    
                        }
    
    #endregion
    
                        #region CMSten tüm branslar getirilecek ve enzimden gelenler ile eşleştirilerek db de update edilecek
    
    
                        await _CMSclient.AuthenticateAsync();
                        var hospitals = await _CMSclient.GetHospitalsAsync(1);
                        var langs = await _CMSclient.GetLanguagesAsync();
                        foreach (var hastane in hospitals)
                        {
                            foreach (var lang in langs.Where(x => x.Code != "tr"))
                            {
                                List<MedicalUnit> medicalUnit = await _CMSclient.GetMedicalUnitsByHospitalAsync(hastane.Id, lang.Id);
                                string langCode = lang.Code;
                                if (langCode == "de") langCode = "de-DE";
                                else if (langCode == "bosnah") langCode = "bs";
    
                                foreach (var unit in medicalUnit)
                                {
    
                                    var DbBrans = await _onlineVizitBranslarRepository.GetListAsync(
                                    x => x.EnzimPozisyonId == unit.enzimCode &
                                    x.EnzimHospitalId == unit.HospitalEnzimCode
                                    );
                                    if (DbBrans != null && DbBrans.Count == 1)
                                    {
    
                                        var text = (await _languageRepository.GetListAsync()).FirstOrDefault(l =>
                                          l.CultureName == langCode && l.ResourceName == "EnzimWeb" &&
                                          l.Name == DbBrans.First().AbpLanguageKey);
    
                                        if (text == null)
                                        {
    
                                            await _languageRepository.InsertAsync(
                                              new LanguageText(Guid.NewGuid(), "EnzimWeb", langCode, DbBrans.First().AbpLanguageKey, unit.MedicalUnitName, null)
                                              );
    
                                        }
                                        else
                                        {
    
                                            text.Value = unit.MedicalUnitName;
                                            await _languageRepository.UpdateAsync(text);
    
    
                                        }
    
    
                                        var updateSonuc = await _onlineVizitBranslarManager.UpdateAsync(DbBrans.First().Id, DbBrans.First().RandevuAlinabilirmi, DbBrans.First().BransAdi, DbBrans.First().EnzimPozisyonId
                                            , unit.MedicalUnitID.ToString(), hastane.Id.ToString(), DbBrans.First().EnzimHospitalId, "https://www.medicana.com.tr/tibbi-birimler/" + unit.MedicalUnitURL
                                            , DbBrans.First().AbpLanguageKey);
                                    }
    
    
    
                                }
                            }
                        }
    
    
                        #endregion
    
                        ExceptionlessClient.Default
                        .CreateLog("Info")
                        .AddTags("endJob", "EnzimOnlineVizitBransListesiWorker")
                        .Submit();
    
                    }
                    catch (Exception ex)
                    {
    
                        ExceptionlessClient.Default
                       .CreateLog("Error")
                       .AddObject(ex, "ex")
                       .AddTags("response", "EnzimOnlineVizitBransListesiWorker")
                       .Submit();
                        throw;
                    }
                }
            }
    
            public static string Temizle(string input)
            {
                if (string.IsNullOrWhiteSpace(input))
                    return string.Empty;
    
                // Türkçe karakterleri İngilizce karşılıklarına çevir
                var karakterMap = new Dictionary<char, char>
            {
                { 'ç', 'c' }, { 'Ç', 'C' },
                { 'ğ', 'g' }, { 'Ğ', 'G' },
                { 'ı', 'i' }, { 'İ', 'I' },
                { 'ö', 'o' }, { 'Ö', 'O' },
                { 'ş', 's' }, { 'Ş', 'S' },
                { 'ü', 'u' }, { 'Ü', 'U' }
            };
    
                var sb = new StringBuilder();
    
                foreach (char c in input)
                {
                    if (karakterMap.ContainsKey(c))
                        sb.Append(karakterMap[c]);
                    else
                        sb.Append(c);
                }
    
                // Noktalama işaretlerini ve boşlukları temizle
                string sonuc = Regex.Replace(sb.ToString(), @"[\p{P}\p{S}\s]+", "");
    
                return sonuc;
            }
        }
    }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The error occur at _randevuWS.HastaneAraAsync(hastaneAraIstek);

    Please share the HastaneAraAsync method code.

    Thanks.

  • User Avatar
    0
    cetin.sahin created
    public async Task<HastaneAraCevap> HastaneAraAsync(HastaneAraIstek istek) 
    { 
        await EnsureTokenAsync(); 
        return await _client.HastaneAraAsync(istek);
    }
    
    private async Task EnsureTokenAsync()
    {
        try
        {
            if (string.IsNullOrEmpty(_token))
            {
                var loginIstek = new LoginIstek { KullaniciAdi = _username, Sifre = _password };
                var loginSonuc = await _authClient.LoginAsync(loginIstek);
                _token = loginSonuc.Token;
                if (!_client.Endpoint.EndpointBehaviors.Any(b => b is AuthHeaderEndpointBehavior))
                {
                    _client.Endpoint.EndpointBehaviors.Add(new AuthHeaderEndpointBehavior(_token));
                }
            }
        }
        catch (Exception ex)
        {
            string mesaj = ex.Message;
            throw;
        }
    
    }
    
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Does the HastaneAraAsync method use a token to request the API?

    Can you write the token to the logs?

    I think it has expired. How did you obtain the token?

    Thanks

  • User Avatar
    0
    cetin.sahin created

    This error is not related to abp.io. We've determined that it's related to the token expiration date of the service we're calling. The solution in the link below was misleading. Thank you for your help. Sorry. We'd appreciate it if you could refund the ticket.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    I'm glad you solved the problem. 👍

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.0.0-preview. Updated on September 18, 2025, 07:10