Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net identity slidingexpiration set to true does not re-issues cookie

I'm using ASP.Net identity authentication to control my application authorization, i need to terminate users sessions after specified minutes of inactivity, I tried to achivieve this by doing the following aproach

public void ConfigureAuth(IAppBuilder app) {
    app.CreatePerOwinContext<UserStore>(() => new UserStore());
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

    app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/login"),
        LogoutPath = new PathString("/logout"),
        CookieDomain = ConfigurationManager.AppSettings["CookieDomain"],
        Provider = new CookieAuthenticationProvider {
            // Enables the application to validate the security stamp when the user logs in.
            // This is a security feature which is used when you change a password or add an external login to your account.  
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                validateInterval: TimeSpan.FromMinutes(2),
                regenerateIdentity: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie)
            )
        },
        SlidingExpiration = true,
    });
}

And I also tried this aproach

app.UseCookieAuthentication(new CookieAuthenticationOptions {
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/login"),
    LogoutPath = new PathString("/logout"),
    CookieDomain = ConfigurationManager.AppSettings["CookieDomain"],
    ExpireTimeSpan = TimeSpan.FromMinutes(2),
    SlidingExpiration = true,
});

Using those aproches user cookie session expired after 2 minutes no matter if the user was active in the site. I read in the documentation that by setting SlidingExpiration = true the cookie would be re-issued on any request half way through the ExpireTimeSpan. For example, if the user logged in and then made a second request 16 minutes later the cookie would be re-issued for another 30 minutes. If the user logged in and then made a second request 31 minutes later then the user would be prompted to log in.

I don't know why it is not working, any ideas?

like image 449
Miguel Antonio Blanco Salcedo Avatar asked Aug 16 '16 19:08

Miguel Antonio Blanco Salcedo


People also ask

Does ASP NET identity use cookies?

You do not need a separate CookieAuthentication middleware when you are using ASPNET identity. UseIdentity() will do that for you and generate a cookie. You can set the "cookie options" in the AddIdentity block of the application like so: services.

What is SlidingExpiration .NET core?

The SlidingExpiration is set to true to instruct the handler to re-issue a new cookie with a new expiration time any time it processes a request which is more than halfway through the expiration window. public: property bool SlidingExpiration { bool get(); void set(bool value); };

How do I enable cookies in ASP.NET Core?

For a general cookie manually created within your application, you control the flags for security when creating it - for example: Response. Cookies. Append( "COOKIE_NAME", "COOKIE_VALUE", new CookieOptions() { Path = "/", HttpOnly = false, Secure = false } );


1 Answers

To be clear: The CookieHandler is checking if the time remaining until cookie expiration is less than the time elapsed since issue (meaning it's > half expired) before requesting a refresh. This is in the dll for Microsoft.AspNetCore.Authentication.Cookies.

Personally, I would prefer to have an option to change the percentage of elapse. When you're working with very small timeouts (15-mins or less) for more secure apps, having the user timeout after only 7-mins of inactivity, because the cookie never refreshed for the first 6mins they were active, is quite annoying.
Perhaps adding an option to use a remaining timespan check against a constant instead. For example, issue a refresh request when the cookie has less than {TimeSpan} remaining.

private void CheckForRefresh(AuthenticationTicket ticket)
{
  DateTimeOffset utcNow = this.get_Clock().get_UtcNow();
  DateTimeOffset? issuedUtc = ticket.get_Properties().get_IssuedUtc();
  DateTimeOffset? expiresUtc = ticket.get_Properties().get_ExpiresUtc();
  bool? allowRefresh = ticket.get_Properties().get_AllowRefresh();
  bool flag = !allowRefresh.HasValue || allowRefresh.GetValueOrDefault();
  if (((!issuedUtc.HasValue || !expiresUtc.HasValue ? 0 : (this.get_Options().SlidingExpiration ? 1 : 0)) & (flag ? 1 : 0)) == 0)
    return;
  TimeSpan timeSpan = utcNow.Subtract(issuedUtc.Value);
  if (!(expiresUtc.Value.Subtract(utcNow) < timeSpan))
    return;
  this.RequestRefresh(ticket);
}
like image 93
DiscipleMichael Avatar answered Oct 15 '22 13:10

DiscipleMichael