title: Configuring cookies in Asp.Net Core 3.1 with Identity
body: <p>I'm using Asp.Net Core 3.1 with Identity. And here is my all configuration in Startup class.
  I'm trying to force the logged in user to logout if their accounts expired while using the app. I should configure the cookie correctly but i'm stuck on how to do this while having AddIdentity.</p>
  <p>Here is my <strong>Startup</strong></p>
  <pre><code> // This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
          services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt;
             options.UseSqlServer(
                 Configuration.GetConnectionString(&quot;DefaultConnection&quot;)));
  
          services.AddIdentity&lt;IdentityUser, IdentityRole&gt;(options =&gt; {
              options.SignIn.RequireConfirmedAccount = false;
          })
              .AddEntityFrameworkStores&lt;ApplicationDbContext&gt;()
              .AddDefaultTokenProviders(); 
  
          services.AddIdentityCore&lt;ApplicationUser&gt;()
              .AddRoles&lt;IdentityRole&gt;()
              .AddClaimsPrincipalFactory&lt;UserClaimsPrincipalFactory&lt;ApplicationUser, IdentityRole&gt;&gt;()
              .AddEntityFrameworkStores&lt;ApplicationDbContext&gt;()
              //.AddDefaultTokenProviders()  
              .AddDefaultUI(); 
  
          services.AddSingleton&lt;IEmailSender, EmailSender&gt;();
          services.Configure&lt;EmailOptions&gt;(Configuration);
     
          services.AddHangfire(config =&gt; config.UseSqlServerStorage(Configuration.GetConnectionString(&quot;DefaultConnection&quot;)));
          services.AddHangfireServer();
  
          services.AddControllersWithViews(); //?
          services.AddRazorPages().AddRazorRuntimeCompilation(); //?
          services.AddScoped&lt;IExpirationJob, ExpirationJob&gt;();
          services.AddScoped&lt;IReminderJob, EmailReminder&gt;();
          services.AddSingleton&lt;IActionContextAccessor, ActionContextAccessor&gt;();
          services.Configure&lt;IdentityOptions&gt;(options =&gt;
          {
              // Password settings.
              //options.Password.RequireDigit = true;
              //options.Password.RequireLowercase = true;
              //options.Password.RequireNonAlphanumeric = true;
              //options.Password.RequireUppercase = true;
              //options.Password.RequiredLength = 6;
              //options.Password.RequiredUniqueChars = 1;
  
              // Lockout settings.
              //options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
              //options.Lockout.MaxFailedAccessAttempts = 5;
              //options.Lockout.AllowedForNewUsers = true;
  
              // User settings.
              //options.User.AllowedUserNameCharacters =
              //    &quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ &quot;;
              //options.User.RequireUniqueEmail = false;
          });
  
          services.ConfigureApplicationCookie(config =&gt;
          {
              config.Cookie.Name = &quot;my.Cookie&quot;;
              config.LoginPath = &quot;/Home/Login&quot;;
              config.AccessDeniedPath = &quot;/Identity/Account/AccessDenied&quot;;
              config.Cookie.HttpOnly = true;
              config.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
          });
       }
  
      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
      public void Configure(IApplicationBuilder app,
          IWebHostEnvironment env,
          IRecurringJobManager recurringJobManager,
          IServiceProvider serviceProvider)
      {
          if (env.IsDevelopment())
          {
              app.UseDeveloperExceptionPage();
              app.UseDatabaseErrorPage();
          }
          else
          {
              app.UseExceptionHandler(&quot;/Home/Error&quot;);
              // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
              app.UseHsts();
          }
          app.UseHttpsRedirection();
          app.UseStaticFiles();
  
  
          app.UseHangfireDashboard();
          //app.UseHangfireDashboard(&quot;/hangfire&quot;, new DashboardOptions()
          //{
          //    Authorization = new[] { new CustomAuthorizeFilter() }
          //});
  
          app.UseRouting();
  
          app.UseAuthentication();
          app.UseAuthorization();
        
       
          app.UseAuthentication();
          app.UseAuthorization();
        
          recurringJobManager.AddOrUpdate(
             &quot;End Users Subscription&quot;,
             () =&gt; serviceProvider.GetService&lt;IExpirationJob&gt;().SetExpired(),
             Cron.Minutely
             );
  
          recurringJobManager.AddOrUpdate(
             &quot;Send End of Subscription Reminder&quot;,
             () =&gt; serviceProvider.GetService&lt;IReminderJob&gt;().SendReminder(),
             Cron.Daily
             );
  
          app.Use(async (context, next) =&gt;
          {
              _ = ExpirationJob.SetExpired(context);//pass the HttpContext to SetExpired
              await next();
          });
  
          app.UseEndpoints(endpoints =&gt;
          {
              endpoints.MapControllerRoute(
                  name: &quot;default&quot;,
                  pattern: &quot;{controller=Home}/{action=Index}/{id?}&quot;);
              endpoints.MapRazorPages();
          });
      }
  </code></pre>
  <p>Here is my <strong>ValidateAsync</strong> class</p>
  <pre><code> public class ValidateAsync
  {
      public static async Task ValidatingAsync(CookieValidatePrincipalContext context)
      {
          context = context ?? throw new ArgumentNullException(nameof(context));
          var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
          if (claimsIdentity?.Claims == null || !claimsIdentity.Claims.Any())
          {
              await RejectPrincipal();
              return;
          }
          UserManager&lt;IdentityUser&gt; userManager = context.HttpContext.RequestServices.GetRequiredService&lt;UserManager&lt;IdentityUser&gt;&gt;();
          var user = await userManager.FindByNameAsync(context.Principal.FindFirstValue(ClaimTypes.NameIdentifier));
          if (user == null || user.SecurityStamp != context.Principal.FindFirst(new ClaimsIdentityOptions().SecurityStampClaimType)?.Value)
          {
              await RejectPrincipal();
              return;
          }
          async Task RejectPrincipal()
          {
              context.RejectPrincipal();
              await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
          }
      }
  }
  </code></pre>
  <p>Here is my <strong>SetExpired</strong> method</p>
  <pre><code>      public interface IExpirationJob
  {
      Task SetExpired();
  
  }
  public class ExpirationJob : IExpirationJob
  {
      private readonly ApplicationDbContext _db;
      private readonly IEmailSender _emailSender;
      private readonly HttpContext _context;
  
      public ExpirationJob(ApplicationDbContext db, IEmailSender emailSender, HttpContext context)
      {
          _db = db;
          _emailSender = emailSender;
          _context = context;
      }
  
      public async Task SetExpired()
      {
          foreach(var item in _db.Institution)
          {
              if (item.SubsEndDate != null)
              {
                  if (item.SubsEndDate &lt;= DateTime.Now) 
                  {
                     
                      item.Status = SD.StatusExpired;
  
                      Guid securityStamp = Guid.NewGuid();
                      item.Admin.SecurityStamp = securityStamp.ToString();
  
                      _context.Response.Cookies.Append(&quot;my.Cookie&quot;, &quot;expired&quot;);
                  }
              }
          }
          await _db.SaveChangesAsync();
      }
  }
  </code></pre>