Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle cookie expiration in asp.net core

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 cookie is expired is to take few informations out of the current cookie at redirect to a action parametrise by this information. Is it possible ?

like image 705
Dave Avatar asked Aug 11 '16 07:08

Dave


People also ask

How do I expire cookies in .NET core?

HttpOnly = true; options. Cookie. IsEssential = false; }); // Change cookie expiration from "until browser close" to 14 days services.

How do you handle expired cookies?

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.

What is the default expire time of cookie in asp net?

The default time for a Cookie to expire is 30 minutes. The default Expires value for a cookie is not a static time, but it creates a Session cookie. This will stay active until the user closes their browser/clears their cookies. You can override this as required.


3 Answers

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>
        }
    });
}
like image 144
Ashley Lee Avatar answered Sep 25 '22 23:09

Ashley Lee


It looks like you need your own handler for the OnValidatePrincipal event when setting up cookie authentication 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>
    };
});

The ASP.NET documentation contains an example of such a handler:

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");
        }
    }
}
like image 21
Set Avatar answered Sep 25 '22 23:09

Set


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);

}
like image 45
adem caglin Avatar answered Sep 23 '22 23:09

adem caglin