Asp.net Identity Expire Session Cookie

2019-01-24 07:45发布

问题:

We are using MVC 5.2 and the ASP.NET Identity framework for authentication with a form authentication screen (user&password combo) and identity is persisted using a cookie. I have configuration in my startup method for the Identity framework to set the expiration on the authentication cookie to 30 days, this works just fine when the user selects to 'remember me' (IsPersistent = true). When IsPersistent = false (user elects not to select 'Remember me') a Session cookie is created by default. This session cookie works great in Internet Explorer and also FireFox, when the browser is closed the cookie is lost. In Chrome and Safari (and maybe other browsers too) there are options to ensure that session cookies are not lost, in this case the user stays logged in even when the browser is closed and re-opened.

I would like a work around to ensure that session cookies are not persisted forever but are discarded within an hour. I might be able to realize this by checking if the account is not active for X minutes/hours and the user never chose for 'Remember Me' then the users identity is 'rejected' with the next request if that time span elapses.

Has anyone created a work around in their ASP.NET Identity implementation to ensure that session cookies are expired on the back end after X time or maybe there is a better way to work around this limitation? Maybe it is possible to do this using a custom implementation of the CookieAuthenticationProvider or hand an expiration date/time to the user claim which can be checked somewhere in the ValidateIdentity process?

Any ideas would be great. Thank you in advance, -Igor

Edit - more information: My authentication implementation has 2 basic "modes" (can't think of a better word at the moment). My implementation is for a simple username/password form with a checkbox 'remember me'. The checkbox value is passed to the IsPersistent property of the AuthenticationProperties object which is passed to the AuthenticationManager::SignIn method.

  1. User wants to 'remember me' which creates a long lived cookie with an expiration of 30 days set using a sliding expiration. This enables the user to stay authenticated between browser sessions and there is no time out due to inactivity with the exception of not visiting the site for longer than 30 days. The settings in my owin startup method reflect that the expiration time for the cookie is 30 days (CookieAuthenticationOptions.ExpireTimeSpan set to 30 days). This works regardless of browser platform (as far as I can tell).

  2. User does not want to 'remember me', what the expected behavior should be is a session cookie is created and when a browser is closed the session cookie is removed from the browser. This should ensure that the next time the browser is started the user is not authenticated. This is especially important when a shared device is being used like a public computer. The problem is not all browsers always delete session cookies, some leave them on purpose if a browser setting is enabled (Chrome is a good example). A session cookie does not have an expiration date/time so CookieAuthenticationOptions.ExpireTimeSpan has no affect here. This is where I am looking for advice as I am sure I can't be the first one who has come across this. There is probably a way to make this behavior more secure as the alternative is to do nothing and possibly leave a session cookie (which never expires!) on the browser.

See this link for more detail on Chrome and session cookies.

回答1:

Identity already embeds expiry time in the cookie data and it is checked by OWIN.

To limit cookie life set ExpireTimeSpan to an hour in ConfigureAuth method in Startup.Auth.cs:

public void ConfigureAuth(IAppBuilder app)
{
    // other stuff
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        ExpireTimeSpan = TimeSpan.FromHours(1),
    });            
}

This will make sure cookies will expire in an hour.



回答2:

In Google Chrome it has to do with a setting named Continue where I left off.

In FireFox I believe the setting is Show my windows and tabs from last time.

If this setting is enabled (in your above browser of choice) then session cookies will not be deleted, the state of your cookie does not matter. There is no direct work around for this using cookie properties.


Possible ideas for a work around

JavaScript

You could listen to the window event window.onbeforeunload and then manually delete the cookie at that point in time or ask the server to invalidate it if the user opted to not remember him/her. This approach assumes the cookie is not Http only OR that you can change the user's security stamp in the database so the next time they visit the site on that browser the cookie is invalidated. This might be the best approach to use but maybe someone else has a better idea.

Polling

Using something like SignalR you could check to see if the clients can still actively respond after authentication (pick some arbitrary time interval). If the client cannot be reached then invalidate their session by changing the user's security stamp. This would require that the server maintains a list of active clients so it knows who to contact and invalidate if contact fails. I for see a lot of problems with this approach, I have a feeling this would create very brittle code with some possible pit falls like the server not being available if there is a short network interference.