manage form data with cookies and servlets - servlets

I've been checking info about cookies data persistence and retrival. it seems that cookies can only manage key value pairs, i want to store data from a form (like name, description, age, number, gender, etc). Is this possible? i saw some examples with javascript but i am not very sure about that.
I'm using spring mvc 2.5, it allows me to access HttpSeesion, HttpServletRequest and HttpServletResponse.
I have already done some exercises retriving and storing a value.
I want to try this way because at this moment the data comming from forms are handled by session. and not always the session is cleaned up.

Storing large and/or user-sensitive data in a cookie is a poor practice. Cookies are fully exposed into public and they have huge limitations as to the available storage space.
Rather autogenerate a long, unique and near-impossible-to-bruteforce ID (java.util.UUID is helpful in this), store it in a cookie. Finally use this ID as key in a Map or a SQL database in the server side where you store the data. This way you will be able to associate the desired data with the ID as found in the cookie.
Update as per the comments, your concern turns out to be the server memory usage (I initially understood that it was the session lifetime being too short). The first paragraph of the answer still stands: You really don't want to do that. This is a security hole and the cookie space is very limited.
As to the actual concern: just give your server more memory, or configure it to store sessions on disk, or just manually store the data in a DB along a key in session scope.

Related

How to add claim to user dynamically?

I want to save some small info (say, user's device id) about the user, after or during sign-in. This data is dynamic, and I'd like the lookup to be very fast (without database hit), as I need it in many controllers. I tried adding it to user's claims like this:
((ClaimsIdentity)User.Identity).AddClaim(new Claim("UserDeviceId", userDeviceId));
to subsequently retrieve it like this: User.FindFirstValue("UserDeviceId") inside any controller. But it seems that the data is not persisted between requests! It returns NULL on another HTTP request.
I use standard SingInManager.PasswordSignIn() to sign the user in. I don't have claim store at all - I don't use default Identity EF implementation, I supply my own stores (IUserStore, IUserPasswordStore, and IUserRoleStore implementations). But even if I did, this data is dynamic and should not be persisted to / retrieved from a storage at all. The data is available upon sign in (basically client app sends hardware id).
As I understand, the dynamically added claim gets wiped out because it is never injected into the cookie, when I add it to User.Identity it just adds to in-memory instance, which gets overwritten by the cookie at next request. (or at least that's my best guess).
Is there any solution to this problem? I'd really like to avoid setting up Session mechanism, all I need is a single small value persisted across the requests, and even though strictly speaking it might not fully qualify as a "user claim", it is (conceptually) very close - it is a device id the user is currently connected from.
I use User.FindFirstValue(ClaimTypes.NameIdentifier) in my controllers to get userId without any performance impact, and it is very convenient. It's setup by Identity itself obviously. I'd like to have similar mechanism for another identifier, preferably without rewriting half of Asp.Net Identity :) Is that doable? If not, what's my best alternative (besides setting up Session storage or supplying the value in every request)?

Disadvantage of using session[""] in asp.net

In my project I use session to store user information ( username, password, personal image, and gender ) to be used in all pages of my project. I also use two other session to store small strings. Is there any disadvantage of using session ? also is there any risk of using session to store user password ?
Some things to take into account:
Don't store passwords. You should hash the incoming password, validate against the hash in your DB, and not hold on to it afterwards.
You should try to avoid using a write-access Session throughout the application, since you'll end up forcing asp.net to serialize incoming requests from the same session. Use read-only Session to avoid that. This could become apparent if you initiate multiple ajax calls simultaneously. More info here: https://connect.microsoft.com/VisualStudio/feedback/details/610820/session-based-asp-net-requests-are-serialized-and-processed-in-a-seemingly-inverse-order
Storing too much data in the Session could cause scalability issues, since all that information is held in memory on the server. If you switch over to SQL storage for sessions (common in webfarm/cloud deployments), then if the session is large every request on the server will have that Session data going back and forth between the server and the DB.
Content that goes into the session should be Serializable, just in case you decide to move over to a different persistent storage (such as sql server)
Using Sessions to retain information may not go well with stateless REST/WebApi endpoints (if you need to create any in the future)
Excessive use of Session for storage could make unit testing slightly more difficult (you will have to mock the Session)
By "personal image" I assume you are storing a url or such, and not an actual binary image. Avoid storing binary content. Only return the binary image file when the browser requests it, and don't store it in memory, the browser can cache that content easily.
You might also find the references linked in this answer to be useful in providing additional information: https://stackoverflow.com/a/15878291/1373170
The main problem with using Session and any machine depending properties is the scalability of the web site, so if you wanted to deploy your web site to a farm of servers then you can see the problem with depending on a machine state property since the request may be processed on different machines.
Hope that helps.

What is the best way to store temporary user information in asp.net?

When user logs in there are number of attributes I need to retrieve from ActiveDirectory such as their real name, some contacts etc. Some of these fields I will be showing quite often in some forms. ActiveDirectory retrieval speed is pretty bad in my case, so I was wondering what would be the best way to store this information in memory when they log in, and then delete it once they log off/timeout?
My thoughts so far:
1) Store in Session, but is it safe?
2) Extend the User.Identity and store it there. Not sure that's possible.
3) Store it in some kind of global Dictionary. How would I know that they logged off to remove the key/value pair?
I am using MVC2 for this project and I will not need to write back to ActiveDirectory.
Session objects are quite commonly used for storing information. If you are worried about security, you can use HTTPS for communication or you can make use of State Servers or SQL Server for storing that information.
Yes as it is said you can use profile provider to store the data.
I personally use session data.
my view why:
1, Database solution via adding field into profile (as additionalUserData = data in here)
Make it simple to use and does not take long to implement as session handling.
2, session data are always on server and there for you do not need to care about data in database, and works without it. (few project has been done this way)
it is reasonably save and easy to access and you can add expiry date time. Also you can keep more information about the user.
3th option:
You would have to have timestamp and checking every request which has expired and remove this records in which case you would have to have dictionary for every user...
The problem is yours....
Hope it helps
I would put it in session as long as it's not a large amount of data. Seems like it's a perfect fit for session state. There shouldn't be any safety concerns if you use https.
If you're concerned about the amount of data you'd be putting in session state you could also consider using the ASP.NET Profile Provider but you'd need to have some type of mechanism to keep the data synched with AD (maybe each time the user logs in). That being said, if it's not a huge amount of data I think session is the way to go.

Caching user data in asp.net application

What's the best way to cache web site user data in asp.net 4.0?
I have a table of user settings that track all kinds of user or session specific stuff like the state of UI elements (open/closed), preferences, whether some dialog has been dismissed, and so on. Since these don't change very often (for each user, anyway) but are looked up frequently it seems sensible to cache them. What's the best way? These are the options I've identified...
Store them in HttpContext.Current.Session directly (e.g. Session["setting_name"])
Store them in HttpContext.Current.Cache
Use a global static dictionary, e.g. static ConcurrentDictionary<string,string> where the key is a unique userID + setting name value
Store a dictionary object for each session in Session or Cache
What's the most sensible way to do this? How does Session differ from Cache from a practical standpoint? Would it ever make sense to store a dictionary as a single session/cache object versus just adding lots of values directly? I would think lookups might be faster, but updates would be slower since I'd have to re-store the entire dictionary when it changed.
What problems or benefits might there be to using a global static cache? Seems like this would be the fastest, but I'd have to manage the size. I could just flush it periodically if it hits a certain size, or keep a cross reference queue and remove things oldest first when it gets to a certain size. Does this make any sense or is it just trying too hard?
Session may end up being stored out-of-process or in a database, which can make retrieving it expensive. You would likely be using a session database if your application is to be hosted in a server farm, as opposed to a single server. A server farm provides improved scalability and reliability, and it's often a common deployment scenario. Have you thought about that?
Also, when you use Session not in-process, it ends up getting serialized to be sent out-of-process or to a database, and deserialized when retrieved, and you are effectively doing what you describe above:
... updates would be slower since I'd have
to re-store the entire dictionary when
it changed. ...
.. since, even if you use individual session keys, the entire Session object for a user is serialized and deserialized together (all at once).
Whereas, Cache would be in memory on a particular server in the farm, and therefore much more efficient than going out of process or to the database. However, something in cache on one server might not be in cache on another. So if a user's subsequent request is directed to another server in the farm, the cache on that server might not yet hold any of the user's items.
Nevertheless, I'd suggest you use Cache if you're caching for performance reasons.
p.s. Yes, you're trying too hard. Don't reinvent the wheel unless you really need to. :-)
might be better to put your information into memcached for scalability

ASP.Net Session

I am wanting to store the "state" of some actions the user is performing in a series of different ASP.Net webforms. What are my choices for persisting state, and what are the pros/cons of each solution?
I have been using Session objects, and using some helper methods to strongly type the objects:
public static Account GetCurrentAccount(HttpSessionState session)
{
return (Account)session[ACCOUNT];
}
public static void SetCurrentAccount(Account obj, HttpSessionState session)
{
session[ACCOUNT] = obj;
}
I have been told by numerous sources that "Session is evil", so that is really the root cause of this question. I want to know what you think "best practice", and why.
There is nothing inherently evil with session state.
There are a couple of things to keep in mind that might bite you though:
If the user presses the browser back button you go back to the previous page but your session state is not reverted. So your CurrentAccount might not be what it originally was on the page.
ASP.NET processes can get recycled by IIS. When that happens you next request will start a new process. If you are using in process session state, the default, it will be gone :-(
Session can also timeout with the same result if the user isn't active for some time. This defaults to 20 minutes so a nice lunch will do it.
Using out of process session state requires all objects stored in session state to be serializable.
If the user opens a second browser window he will expect to have a second and distinct application but the session state is most likely going to be shared between to two. So changing the CurrentAccount in one browser window will do the same in the other.
Your two choices for temporarily storing form data are, first, to store each form's information in session state variable(s) and, second, to pass the form information along using URL parameters. Using Cookies as a potential third option is simply not workable for the simple reason that many of your visitors are likely to have cookies turned off (this doesn't affect session cookies, however). Also, I am assuming by the nature of your question that you do not want to store this information in a database table until it is fully committed.
Using Session variable(s) is the classic solution to this problem but it does suffer from a few drawbacks. Among these are (1) large amounts of data can use up server RAM if you are using inproc session management, (2) sharing session variables across multiple servers in a server farm requires additional considerations, and (3) a professionally-designed app must guard against session expiration (don't just cast a session variable and use it - if the session has expired the cast will throw an error). However, for the vast majority of applications, session variables are unquestionably the way to go.
The alternative is to pass each form's information along in the URL. The primary problem with this approach is that you'll have to be extremely careful about "passing along" information. For example, if you are collecting information in four pages, you would need to collect information in the first, pass it in the URL to the second page where you must store it in that page's viewstate. Then, when calling the third page, you'll collect form data from the second page plus the viewstate variables and encode both in the URL, etc. If you have five or more pages or if the visitor will be jumping around the site, you'll have a real mess on your hands. Keep in mind also that all information will need to A) be serialized to a URL-safe string and B) encoded in such a manner as to prevent simple URL-based hacks (e.g. if you put the price in clear-text and pass it along, someone could change the price). Note that you can reduce some of these problems by creating a kind of "session manager" and have it manage the URL strings for you but you would still have to be extremely sensitive to the possibility that any given link could blow away someone's entire session if it isn't managed properly.
In the end, I use URL variables only for passing along very limited data from one page to the next (e.g. an item's ID as encoded in a link to that item).
Let us assume, then, that you would indeed manage a user's data using the built-in Sessions capability. Why would someone tell you that "Session is evil"? Well, in addition to the memory load, server-farm, and expiration considerations presented above, the primary critique of Session variables that they are, effectively, untyped variables.
Fortunately, prudent use of Session variables can avoid memory problems (big items should be kept in the database anyhow) and if you are running a site large enough to need a server farm, there are plenty of mechanisms available for sharing state built in to ASP.NET (hint: you will not use inproc storage).
To avoid essentially all of the rest of Session's drawbacks, I recommend that implement an object to hold your session data as well as some simple Session object management capabilities. Then build these into a descendent of the Page class and use this descendent Page class for all of your pages. It is then a simple matter to access your Session data via the page class as a set of strongly-typed values. Note that your Object's fields will give you a way to access each of your "session variables" in a strongly typed manner (e.g. one field per variable).
Let me know if this is a straightforward task for you or if you'd like some sample code!
As far as I know, Session is the intended way of storing this information. Please keep in mind that session state generally is stored in the process by default. If you have multiple web servers, or if there is an IIS reboot, you lose session state. This can be fixed by using a ASP.NET State Service, or even an SQL database to store sessions. This ensures people get their session back, even if they are rerouted to a different web server, or in case of a recycle of the worker process.
One of the reasons for its sinister reputation is that hurried developers overuse it with string literals in UI code (rather than a helper class like yours) as the item keys, and end up with a big bag of untestable promiscuous state. Some sort of wrapper is an entry-level requirement for non-evil session use.
As for "Session being evil" ... if you were developing in classic ASP I would have to agree, but ASP.NET/IIS does a much better job.
The real question is what is the best way to maintain state. In our case, when it comes to the current logged in user, we store that object in Session, as we are constantly referring to it for their name, email address, authorization and so forth.
Other little tidbits of information that doesn't need any long-term persistence we use a combination of cookies and viewstate.
When you want to store information that can be accessed globally in your web application, a way of doing this is the ThreadStatic attribute. This turns a static member of a Class into a member that is shared by the current thread, but not other threads. The advantage of ThreadStatic is that you don't have to have a web context available. For instance, if you have a back end that does not reference System.Web, but want to share information there as well, you can set the user's id at the beginning of every request in the ThreadStatic property, and reference it in your dependency without the need of having access to the Session object.
Because it is static but only to a single thread, we ensure that other simultaneous visitors don't get our session. This works, as long as you ensure that the property is reset for every request. This makes it an ideal companion to cookies.
I think using Session object is OK in this case, but you should remember Session can expire if there is no browser activity for long time (HttpSessionState.Timeout property determines in how many minutes session-state provider terminates the session), so it's better to check for value existence before return:
public static Account GetCurrentAccount(HttpSessionState session)
{
if (Session[ACCOUNT]!=null)
return (Account)Session[ACCOUNT];
else
throw new Exception("Can't get current account. Session expired.");
}
http://www.tigraine.at/2008/07/17/session-handling-in-aspnet/
hope this helps.
Short term information, that only needs to live until the next request, can also be stored in the ViewState. This means that objects are serialized and stored in the page sent to the browser, which is then posted back to the server on a click event or similar. Then the ViewState is decoded and turned into objects again, ready to be retrieved.
Sessions are not evil, they serve an important function in ASP.NET application, serving data that must be shared between multiple pages during a user's "session". There are some suggestions, I would say to use SQL Session management when ever possible, and make certain that the objects you are using in your session collection are "serializable". The best practices would be to use the session object when you absolutely need to share state information across pages, and don't use it when you don't need to. The information is not going to be available client side, A session key is kept either in a cookie, or through the query string, or using other methods depending on how it is configured, and then the session objects are available in the database table (unless you use InProc, in which case your sessions will have the chance of being blown away during a reload of the site, or will be rendered almost useless in most clustered environments).
I think the "evil" comes from over-using the session. If you just stick anything and everything in it (like using global variables for everything) you will end up having poor performance and just a mess.
Anything you put in the session object stays there for the duration of the session unless it is cleaned up. Poor management of memory stored using inproc and stateserver will force you to scale out earlier than necessary. Store only an ID for the session/user in the session and load what is needed into the cache object on demand using a helper class. That way you can fine tune it's lifetime according to how often that data us used. The next version of asp.net may have a distributed cache(rumor).
Session as evil: Not in ASP.NET, properly configured. Yes, it's ideal to be as stateless as possible, but the reality is that you can't get there from here. You can, however, make Session behave in ways that lessen its impact -- Notably StateServer or database sessions.

Resources