Caching account information - asp.net-mvc

I currently using my own membership implementation on a ASP.MVC project. I've got an Account and an Account can have more than 1 memberships.
I am not sure what is the best approach to follow with Account information being cached. I am currently loading the account information for almost each request from the User property of the controller.
Should I cache the account information? And if where would be the best place, cookies or Session?

I recommend fairly strongly against sessions. They won't scale well and do not fit into web/HTTP type of architectures. See 'Key REST principles' in this REST article if you like the REST stuff.
I would suggest to put the user information in cookies (don't over do it, just really required stuff).
And keep sensitive information in the ASP.NET Forms authentication cookie. See Forms Authentication article, "Step 4: Storing Additional User Data in the Ticket".
Fetch the rest of the data from the database. Avoid premature optimization.

As is often the case with these questions, the answer is "it depends".
Cookies are fine if you are only storing small amounts of string data. There are limitations (4k per cookie, HTTP header limit) and they are sent across the wire with every request and response. You might have to "re-inflate" your account/member info from data stored in the cookie. Users can opt to not accept cookies from your website.
Session is strongly-typed (no re-inflation) and not transmitted with every request/response. There are several options for scaling up session storage if you think your web app will need it. Most small-medium sites use session with no problems.

Related

Rails app with different session store for each model

I have two models doing login (Devise) in my Rails app - Admin and User, both currently use the default cookie store for session data.
I want to be able to identify an Admin session in AJAX requests coming in from the admin, for authorization of these API calls. I plan to do this by setting an encrypted cookie upon Admin login. When the AJAX API call comes in, I open the cookie, grab some identification from it and look for a matching existing Admin session in the store.
As I understand it, to do this, I must have session information stored in the back-end, either by DB or memcache stores.
I expect to have millions of sessions of Users and just a few sessions of Admin at any given time. For this reason, I don't want to just move all session information to a DB or memory, since this is a heap of unneeded data to store. I only want to store/look at Admin session data.
A solution will be creating some custom model which enumerates Admin user sessions, and is maintained by the app. This is simple enough but requires for instance, a way to clean up sessions when they die without signing out. Essentially this is an attempt to duplicate Rails's session store mechanism, which comes with all the problems of storing and maintaining sessions. Instinct tells me to avoid this solution. Am I correct to avoid it?
If so, then my question is, is there a way to configure multiple session stores in a Rails app, a different store for every logged in Model? In this case, have Admin sessions stored in memory, and User sessions stored in cookie. If not, I'll greatly appreciate any comments and suggestions.
Thanks!
You may be thinking about it wrong.
Session are a low level mechanism that you build your authentication on top of. Its just a cookie containing an identifier (a random hash) which is linked to a session storage (by default cookies). This is a simple mechanism to add persistence to a stateless protocol.
Confusingly we also use the concept "sessions" when talking about authentication - for example logging a user in is often referred to as "creating a session". This is complete poppycock as we are just storing a claim (often a user id) in the session that was created when the user first visits the application.
If so, then my question is, is there a way to configure multiple
session stores in a Rails app, a different store for every logged in
Model?
No. Thats a chicken-vs-egg conundrum. In order to know which session storage to use you would need to access the session storage to know which session storage to use... you get the picture.
While you could create your own session storage mechanism that works differently does this is most likely a complete waste of time. Premature optimization is the root of all evil.
As I understand it, to do this, I must have session information stored
in the back-end, either by DB or memcache stores.
Not quite true. You can perfectly well build an authentication solution with just the cookie storage. In that case Rails just keeps a record on the server of which session identifiers are valid.
The main reason you would need to store additional session information in the database or memcached is if you need to store more data in the session than the 4093 bytes allowed by a cookie. Cookie storage is after all much faster and does the job fine 99% of the time. YAGNI.
You should also recognize that not everything needs to be saved in the session storage. For example the Devise trackable module saves log in / out timestamps on the user table as part of the process of authenticating a user. This is "session information" yet has nothing to do with session storage.
I want to be able to identify an Admin session in AJAX requests coming
in from the admin, for authorization of these API calls.
There are many ways to use different authentication logic for different parts of the application such as Warden strategies. For an API you may want to consider using stateless (and sessionless) authentication such as JWT.

ASP MVC5 (C#) Securely cache sensitive user information

I need to securely store sensitive user data between posts. I've read numerous posts on the pros&cons of both session and application caching, but still don't have a clear winner.
Here's the scenario:
User inputs sensitive information and posts it to the server. He is sent to a read only confirmation screen and asked for an OTP (sent via SMS). Then the data gets posted to the server again. On the second post I need to check that the viewmodel info has not been tampered with and verify the OTP.
So the viewmodel info needs to be cached on the first post, and compared on the second post. This viewmodel contains very sensitive information, so it needs to be stored as securely as possible.
I've though of using session to store an encrypted user data store object, but I'm still not entirely convinced that that would be the best solution?
Advise and guidance on this matter would be greatly appreciated!
If you finally going to store this data in the DB, I assume that you find your DB secure enough for this data. A solution could be storing this data in the DB on the first POST with some additional property that states whether this data is verified (I'll refer to it as IsVerified). Once user verifies the OTP simply set this IsVerified property to true.
Pros of this solution in comparison to session storage are:
You don't have to worry about session expiration. (In case that SMS is delayed for example)
If you are going to have a load-balancer, you won't be able to use sticky session to store your data which means that you will have to use some more advanced session management.
User don't have to submit this sensitive data twice, which means that you don't have to re-validate id.

Storing sensitive data in HttpContext.Current

ASP.NET MVC Web application where I am wanting to hold on some sensitive information (an account number) while the user navigates from page to page. I currently am using FormsAuthentication and storing it in a custom IPrinciple. I've encrypted the session cookie and set it to be HttpOnly (can't be accessed via client-script only). This seems like a good and secure solution to me.
However, I've been told we probably want zero sensitive information in a cookie for any reason. So an alternative I'm considering is storing the sensitive information in HttpContext.Current.Items. This would require the user to re-log in for each request but that's ok in this case. They should never come to the site directly, but through links from other sites (which posts authentication information, so the user never manually logs in).
Is there any reason not to use HttpContext.Current for this purpose?

How should I secure my SPA and Web.API?

I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/

mvc site, most secure way to preserve login credentials

ok so, i have this dilemma on how i should save login credentials in mvc at the same time avoid as much hit on the database. i know i can easily use Forms Authentication to save a User instance but is it advisable?
At the moment the way I do it is I store the User Id in a cookie which i then would access everytime an Action gets called that would "require" a login access. Before the action gets accessed the User Id will be used to retrieve a "New" User instance. This will be the same on every Action, I don't store the User in the cookie as I feel like once the cookie is compromised everything about the User shall be available for the hacker (Userid, email, roles, etc)
So if i have a ton of actions that would require a login that will be difficult on my bandwidth. What do you think of the method I'm using? Should I change it to have all the User object be stored in the cookie with a short timeout? Any ideas are greatly appreciated.
thanks!!
It seems like you are trying to address a bandwidth issue. That alone would suggest that you shouldn't store more than you have to (ie: session id) in the cookie.
There are two major problems (among others) for using cookies.
1) They are sent up on every request
2) There is only limited amount of information you can store.
In general, trusting anything the user gives you (that includes encrypted cookies) is bad.
How many concurrent users do you foresee having on your website? Keep in mind that the database will be able to cache certain calls. Furthermore, if you are using a ORM like nhibernate, you will get 2nd level caching there. If all else fails, could you use the in-memory session management?
The biggest problem I have with putting userid's in the cookie is the entropy of that key. Say your userId is an email. All I have to do as an attacker is guess a userid that is valid in your system, and I will "automatically" become that user. The reason why people use sessionID's and then retrieve the user is that in theory sessionID's are harder to guess.
My suggestion would be to use database session management if you are in a load balanced situation. If not, use in-memory. It is fast. Memory is cheap. And unless you are storing 10's of mb of data in session for each user, and you have 10000's of users, you should be fine.
As Ken stated, you should probably be using the standard [authorize] tags available with MVC as opposed to creating your own method.
It sounds like you pretty much implemented form based authentication and something comparable to the [Authorize] attribute.
So if i have a ton of actions that would require a login that will be difficult on my bandwidth
Forms Authentication uses a cookie and is baked into the system. If you don't want to store your user information in SQLServer there are plenty of other options.
It sounds like you are trying to implement something that is already done. In my opinion, let's leave the security stuff to people that know about security. I would suggest working within the framework provided unless you have proof that you solution needs something else!
There is a UserData property on the FormsAuthenticationTicket object that could be used to store additional data other than the Username.
I had a project that had a similar need. I stored the values as a NameValueCollection encoded like a query string:
"email=myemail#some.com&roles=Somebody&roles=Special"
(there's also a handy HttpUtility.ParseQueryString() method that is useful for getting the values back out of the UserData property)
You can use the FormsAuthentication.Encrypt and FormsAuthentication.Decrypt to convert the ticket to and from the Cookie value.

Resources