9

In my startup class, I am enabling session storage with this line:

        services.AddDistributedMemoryCache()
        .AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(20);
                options.Cookie.HttpOnly = true;
            })

However, if I understand this correctly, setting the IdleTimeout property simply states that the session will begin anew if the user does not complete any actions for > 20 minutes. My app has polling which uses user information in the session storage every 5-10 seconds, so I don't think this would ever be of use here. User permissions and roles can change from actions made outside of the current user's browser, so I would like to limit the session storage to 1 minute. I can't seem to find any exact verbiage on what the default expiration is or how to properly set that.

The CookieBuilder class has Expiration and MaxAge options, but I don't know which one is necessary. I've also read that Expiration is ignored, so that adds even more to my confusion in this subject.

Update: I receive this message when I try to set the expiration: "Expiration cannot be set for the cookie defined by SessionOption", so I've set MaxAge to 1 minute, yet I can see that the session still has old user data in it after more than 1 minute has passed.

Dinerdo
  • 560
  • 7
  • 27
  • As I understood just client-request shifts the live time of the session, server-side access to Session shouldn't impact it (you can check it). – vladimir May 03 '19 at 01:41
  • I don't catch how changing some permissions or roles related to the session? Are you storing role/permission info in session? If yes it looks suspicious because an anonymous user has immutable/fixed permissions, when for a registered user they should be stored in persistent storage and be updated there. – vladimir May 03 '19 at 02:00
  • Each request from any user should be passed through [authentication](https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio) and [authorization](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2) checks that not related to the session. – vladimir May 03 '19 at 02:00
  • The user role information is stored in a database. This information rarely ever changes, and I was trying to avoid going to the database for each and every call. All that's stored in the user session is his/her role information. Before any updates or secret information would be displayed to the user, actual tests are performed to verify the user's real role. The cached user settings I'm trying to store are more for visibility options on the home page. – Dinerdo May 03 '19 at 02:34
  • I think you don't need to worry about load data from db (it should be cached I hope), and moreover, authorization metadata is loaded automatically - look at [HttpContext.Current.User](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal?view=netcore-2.2). Probably you overoptimized your code. – vladimir May 03 '19 at 04:33
  • Yes, it's cached but certain data shouldn't be cached for a very long period of time at least within the context of this application. – Dinerdo May 03 '19 at 22:50
  • HttpContext is the context of HTTP request, not the application. It is created for each [request individually](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httpcontext?view=aspnetcore-2.2). Its lifetime is very short. – vladimir May 03 '19 at 23:02
  • Yes, but my question is specifically about user data stored in the session which I am seeing last for many requests, as it should. I simply want to know how I can force the session data to end after a certain time. The workaround I'm currently using is to store the cached date in the session store and use that date to see if a some amount of time has passed before I manually call session.Clear() – Dinerdo May 03 '19 at 23:15
  • Yes, I understood your question. I seemed that you try to store in session a data, which accessible in HttpContext and it was confused me. The session doesn't have an absolute expiration time but just sliding expiration policy that as you has mentioned defined in *IdleTimeout*-property. Why not just define *options.IdleTimeout = TimeSpan.FromMinutes(1)*? – vladimir May 03 '19 at 23:49
  • 2
    @Dinerdo For explicit control of any cached data expiration, use the [caching API](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.2) directly instead of relying on `Session` expiration (as `IdleTimeout` is independant of cookie expiration ([more info](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-2.2)). You can eg. `Set` a value with a `TimeSpan` expiration, being absolute or sliding. – pfx May 04 '19 at 20:47
  • @pfx That makes sense. My issue was that I'm migrating and adding features to an older app someone else originally created, and the original app used session storage all over the place so I kept trying to use it as well. I've used the caching API before, but it didn't come to mind for this situation for some reason.. Thank you for the simple suggestion. – Dinerdo May 05 '19 at 10:31
  • @Dinerdo If you change data from app you should trigger your cache to get new data. I assumed that you change data directly from db, so if it is possible why you try cache it? It is architecture problem. Data should be updated by logic which can trigger cache. maybe look how they do this in asp boilerplate. – CrazyBaran May 07 '19 at 12:48
  • @CrazyBaran Yes I can do that with a shared cache as pfx mentioned. I couldn't figure out how to do that using the session cache though but I don't think I'll use that after this conversation. – Dinerdo May 07 '19 at 16:05

1 Answers1

6

Session does not have an 'expiration' like cookies do, but the default Idle Timeout is 20 minutes, and can be adjusted using the IdleTimeout option.

Session only expires after the idle timeout period has elapsed. Additionally, the idle timeout starts after the last request is received.

For your case, the session will not expire because you poll every 5 - 10 seconds (checking the session data). This polling is seen as a 'request' to the .net core, and resets the timeout.

You can verify this by disabling the polling, and creating a page with a button that checks the session data. Wait for a period of time (ex: 20 seconds), and click the button.

Make sure that you set the Idle Timeout to a low value:

options.IdleTimeout = TimeSpan.FromSeconds(10);

Here is a link to the Documentation on Session.

Tony Abrams
  • 4,505
  • 3
  • 25
  • 32