Click here to Skip to main content
14,177,048 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

295 views
Posted 17 Jan 2017
Licenced CC (ASA 3U)

Conditionally Set Sliding Expiration Time on Authentication Cookies in ASP.NET Core

, 17 Jan 2017
Rate this:
Please Sign up or sign in to vote.
Conditionally set sliding expiration time on authentication cookies in ASP.NET Core

This was one of those days.

Using ASP.NET Core’s cookie middleware for authentication is pretty neat. Once set up properly, it allows us to seamlessly share authentication between our existing 4.6 MVC OWIN application and our new fancy Core SPA.

One key feature is the SlidingExpiration option. This automatically sends a refreshed authentication cookie once the existing cookie is half-way to expiration, ensuring that the user stays logged in for the duration of their session.

However, this might not be what we want for all requests. When continuously polling for updates, we do not want to reset the token. The approach to solve this is the same as for 4.6: Just remove the cookie from the response. This turned out to be quite trickier than expected to get right. The straight-forward solution that worked with 4.6 doesn’t apply here.

The first part is easy: Figure out which requests to separate. We have two options:

  1. Let the client decide (e.g. by query string, request content, HTTP header)
  2. Let the server decide (e.g. separate routes)

We went with #2 and implemented it as a FilterAttribute we would tag our actions with:

/// Prevent the auth cookie from being reset for this action, allows you to
/// have requests that do not reset the sliding login timeout.
public class DoNotResetAuthCookieAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        context.HttpContext.Items.Add("dontRenewAuthCookie", true);
    }
}

Basically, the cookie middleware appends its cookie right before headers are sent to the client. Core doesn’t allow us to remove cookies that are already set; we can only append or expire cookies?—?which would immediately unauthorize the user. So we need to rewrite the Set-Cookie headers. Furthermode, the cookie middleware adds its cookie at the very last moment, so we need to register our handler really late in the pipeline.

public static void UseCactiCookieAuthentication(this IApplicationBuilder app, 
     IHostingEnvironment environment)
{
    var cookieName = "AuthCookie";
    app.Use(next => context =>
    {
        context.Response.OnStarting(state =>
        {
            if(context.Items.ContainsKey("dontRenewAuthCookie"))
            {
                var response = (HttpResponse) state;
                // Omit Set-Cookie header with the offending cookie name
                var cookieHeader = response.Headers[HeaderNames.SetCookie].Where
                 (s => !s.Contains(cookieName)).Aggregate(new StringValues(), 
                 (current, s) => StringValues.Concat(current, s));
                response.Headers[HeaderNames.SetCookie] = cookieHeader;
            }
            return Task.CompletedTask;
        }, context.Response);
        return next(context);
    });

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
        CookiePath = "/",
        CookieName = cookieName,
        AutomaticAuthenticate = true,
        ExpireTimeSpan = TimeSpan.FromMinutes(20),
        AutomaticChallenge = true,
        SlidingExpiration = true,
        CookieSecure = CookieSecurePolicy.Always
        // Additional auth options...
    });
}

Middleware ordering is important here: Since OnStarting callbacks get called LIFO, our cookie-removing callback needs to be added before we add CookieAuthentication.

So there you have it. Core is still a work in progress and I would hope that we can get a more natural way to remove cookies in the future.


Conditionally set sliding expiration time on authentication cookies in ASP.NET Core was originally published in Cacti pins on Medium, where people are continuing the conversation by highlighting and responding to this story.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-Share Alike 3.0 Unported License

Share

About the Author

No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190526.1 | Last Updated 17 Jan 2017
Article Copyright 2017 by Robert Edström
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid