How to handle cookie expiration in asp.net core

后端 未结 3 1452
青春惊慌失措
青春惊慌失措 2021-02-10 02:47

I would like to know how to properly handle the fact that the cookie expired? Is it possible to execute a custom action ?

What I would like to achieve is that when the c

相关标签:
3条回答
  • 2021-02-10 03:00

    Looks like you need your own handler for OnValidatePrincipal event when setuping cokies auth middleware:

    OnValidatePrincipal event can be used to intercept and override validation of the cookie identity

    app.UseCookieAuthentication(options =>
    {
        options.Events = new CookieAuthenticationEvents
        {
            OnValidatePrincipal = <your event handler>
        };
    });
    

    Documentation contains example of such handle:

    public static class LastChangedValidator
    {
        public static async Task ValidateAsync(CookieValidatePrincipalContext context)
        {
            // Pull database from registered DI services.
            var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
            var userPrincipal = context.Principal;
    
            // Look for the last changed claim.
            string lastChanged;
            lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastUpdated"
                           select c.Value).FirstOrDefault();
    
            if (string.IsNullOrEmpty(lastChanged) ||
                !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
            {
                context.RejectPrincipal();
                await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-10 03:04

    There isn't a good way to accomplish this. If the cookie is expired, it is not sent to the server to extract any information. With ASP.Net Core Identity, you don't have much control over that. That leaves you to using Cookie Middleware.

    This provides a user to a normal redirect when the cookie is expired:

    public void ConfigureServices(IServiceCollection services)
    {       
        services.Configure<CookieAuthenticationOptions>(options =>
        {
            options.LoginPath = new PathString("/Home/Index");
        });
    }
    

    The best way to achieve what you're looking for is to set the cookie expiration much later than the true user session expiration, and then perform your session expiration server side and redirect the user at that point. While it's not ideal, you don't have other options when a cookie is expired.

    public void ConfigureServices(IServiceCollection services)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        {
            AuthenticationScheme = "MyCookieMiddlewareInstance",
            // Redirect when cookie expired or not present
            LoginPath = new PathString("/Account/Unauthorized/"),
            AutomaticAuthenticate = true,
            // never expire cookie
            ExpireTimeSpan = TimeSpan.MaxValue,
            Events = new CookieAuthenticationEvents()
            {
                // in custom function set the session expiration
                // via the DB and reset it everytime this is called
                // if the session is still active
                // otherwise, you can redirect if it's invalid
                OnValidatePrincipal = <custom function here>
            }
        });
    }
    
    0 讨论(0)
  • 2021-02-10 03:23

    It seems there is no event for your case but you can use OnRedirectToLogin to change redirect uri. Here is an example:

    OnRedirectToLogin = async (context) =>
    {
          var binding = context.HttpContext.Features.Get<ITlsTokenBindingFeature>()?.GetProvidedTokenBindingId();
          var tlsTokenBinding = binding == null ? null : Convert.ToBase64String(binding);
          var cookie = context.Options.CookieManager.GetRequestCookie(context.HttpContext, context.Options.CookieName);
          if (cookie != null)
          {
                var ticket = context.Options.TicketDataFormat.Unprotect(cookie, tlsTokenBinding);
    
                var expiresUtc = ticket.Properties.ExpiresUtc;
                var currentUtc = context.Options.SystemClock.UtcNow;
                if (expiresUtc != null && expiresUtc.Value < currentUtc)
                {
                      context.RedirectUri += "&p1=yourparameter";
                }
           }
           context.HttpContext.Response.Redirect(context.RedirectUri);
    
    }
    
    0 讨论(0)
提交回复
热议问题