2

In my previous work (ASP.NET webforms) I've used the HttpContext.Current.Session object to hold security-related user data for the current user session, e.g.

Session("userID") = 4525
Session("customerId") = 123
Session("importantValue") = "ABC"

Having learned quite a bit on WebAPI 2, I'm now starting to learn MVC. I am constantly reading that Session and/or HttpContext.Current should be avoided with MVC...

  1. Synchronization and overhead
  2. Session pollutes HTTP
  3. Application collision
  4. AppPool recycling

...but there's not a lot of clarity on simple alternative. Some people say use TempData while others cookies, but both come with downsides as well.

My application is database-heavy, so I want to avoid hitting the database to re-read these values for every request. In WebAPI2 there are bearer tokens that get serialized as cookies. Is the Identity token secure enough to hold this data and avoid user-tampering (if used over SSL)?

Community
  • 1
  • 1
EvilDr
  • 8,943
  • 14
  • 73
  • 133
  • 1
    This is not an easy question, due to the diverse "taste" of developers. If you know what you are doing, there's no harm in using the `Session` object. – Andrei V Aug 27 '14 at 13:38
  • Please link to the sources claiming you should not use sessions ever. There should be considerations, but never say never. If said sources don't motivate why you shouldn't use the session, don't continue reading them. There are perfectly valid reasons in certain scenarios why you shouldn't use sessions, but it is up to you to evaluate whether those scenarios apply to you. – CodeCaster Aug 27 '14 at 13:41
  • The reason a hear over and over is "session hijacking". But with some tweaks this can be completely eliminated. Another is the amount of data you need to store. You have have data amounting to several hundred megabytes, then it would probably be better to use the existing cache mechanism. – Andrei V Aug 27 '14 at 13:43
  • Doesn't `ValidateAntiForgeryToken` overcome session hijacking? I'm only storing a few integer values. – EvilDr Aug 27 '14 at 14:00
  • Question updated to provide clarity on research and other peoples' opinions. – EvilDr Aug 27 '14 at 14:00
  • 1
    @EvilDr: No antiforgery tokens are designed to prevent cross-site request forgery (CSRF). Where some third-party tries to create their own version of a form on your site, but still post to where your form posts. The antiforgery token must be passed with the post to make it valid and there's no way for a third-party to divine what that token will be for any given request. It has nothing to do with sessions. – Chris Pratt Aug 27 '14 at 15:17
  • Are you using OWIN authentication cookie with `ClaimsPrincipal`? – trailmax Aug 27 '14 at 15:29
  • I'm not using OWIN. The older stuff was FormsAuthentication, but now I've got my head around Identity 2.0 I'm planning on using claim-based tokens. – EvilDr Aug 27 '14 at 16:11

1 Answers1

2

Man, I'm not sure where that "use TempData instead of sessions" idea came from, but I'd really like to track down the source and hit them with a blunt object. TempData is session. It uses the session store under the hood. The only difference is that data you put there only survives to the next request, while data placed in Session survives until the session expires. Otherwise, it's exactly the same thing.

That said, there's a lot of debate surrounding this issue and much of it is misguided, leading to only further confusion. The crux of the debate, though, is that sessions are pretty awful things. But, there's really no alternative if you need to add a concept of state.

See, HTTP as a protocol is stateless. Each request is a unique entity, unaffected by any other request before or since. Web API, since you mentioned it, doesn't use sessions because it's what's called "REST-compliant", as in it follows the guidelines of REST. And, REST, which itself is modeled after HTTP, is also stateless. However, this is real life, after all, and you still need to do things like authenticate requests. As a result, things like auth tokens and such are sent either in the request query string or body or via HTTP headers. I'd argue that this is still "sessions", as a traditional session works much the same way: you pass along some "token" with the request, your session id, and the server uses that to recognize you as the same client from a previous request.

So, really, when people argue about sessions, they're not so much arguing about the concept of a session, itself, but really how it's used/abused, even if even they don't realize that's what they're arguing about.

I've seen others argue the merits of using something like Redis or another NoSQL option instead of session, but there you're just arguing about session providers, not sessions.

Personally, I see nothing wrong with using Session in an MVC project, as long as you use it properly. It's great for creating state for things like authenticated users. It would be very annoying to have to login again every time you wanted to request a new page from a site. Other than that, though, I'd pretty much leave it alone. There's very few things that actually should be persisted across multiple requests.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • That's a great answer, thanks. Touching upon your last point, what type of things *should* go in `Session` other than, say, `User.Identity.Name` or a `Role`? I guess that cookie-based authentication tokens are strong enough to be stored on client devices without concern of them being hacked (I think ASP.NET cookies are AES protected then delivered only via SSL)? – EvilDr Aug 27 '14 at 16:09
  • 1
    One example I've personally used is storing a "promo" code in an ecommerce situation. If the user comes from a link with a promo code in it, I save it to the session so that it applies when they checkout. I honestly can't think of many other examples where I've used `Session` explicitly (aside from the implicit use via authentication), which should tell you something about how rare its use should be. – Chris Pratt Aug 27 '14 at 18:00