ASP.NET MVC4 Session state store username - asp.net

I have created my first uber small webapp with MVC4. So far I used the layout stuff to layout the webapp and added some views controllers and a model to register and allow users to log in.
Once a user logged in / registered, I store its username in the session. I read this property from the session to determine if a user has been logged in or not.
Is that a bad practice? I read a lot about RESTful and stateless webapps. I kinda get the feeling that I should not save anything in my session.
e.g.
#if (string.IsNullOrEmpty(Session["User"] as string))
{
<dl>
<dt>Register</dt>
<dt>Login</dt>
</dl>
}
else
{
<dl>
<dt>#Session["User"]</dt>
<dt>Log out</dt>
</dl>
}
Q1: is this a bad practice?
Q2: is this "hack safe"? As is, is it easy to hack the current session and store a value in Session["User"] to bypass logging in?

To answer your questions:
1) In general, using session state is not bad practice, as long as you need it for your applications and you understand its implications on performance and scalability. However, in your case, if all you need to store is the user's name, then you really don't need it, if your application is using an ASP.Net membership provider, then this information is available in the User property in the MVCController base class:
var username = User.Identity.Name
There are three ways that session data can be stored: "InProc", where it is stored in the app process, "StateServer", where it is stored output process on a separate server, and "SQLServer", where it is stored in a SQL Server DB. Which one you should use depends upon if you are using a server farm, if your session needs to be durable (i.e. survive a machine reboot), and what the performance requirements are for your app (StateServer and SQLServer are less performant that InProc). More information can be found here
2) You should use SSL to protect your session data. The data sent over SSL (HTTPS) is fully encrypted, headers included (hence cookies). A good discussion on how to prevent session hijacking attacks is found here.

Related

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.

Do session variables work differently during development?

I'm building a website with ASP.NET MVC3. When a user signs in, I pull their display name from the database and store it to a session variable:
Session["DisplayName"] = user.Display;
Then in _Layout.cshtml I use it to display at the top of each page:
<span class="user">#(Session["DisplayName"] as string)</span>
This works fine when I start debugging the website then log in, but if I then rebuild my server and begin debugging again, my browser remains logged in but the Session variables are cleared. This leads to a bunch of empty spaces where my display name should be.
Is this a side-effect of rebuilding the server, and not something I need to worry about in deployment? Is there a way to invalidate logins every time I rebuild, so that I avoid this issue? Or is there a better way to store this user data, other than a Session variable?
Is this a side-effect of rebuilding the server, and not something I
need to worry about in deployment?
Oh no, that's something that you absolutely should worry about. As you know ASP.NET session is by default stored in server memory. And when the AppDomain is recycled (which could happen at absolutely any time) by IIS all your session is gone. For example IIS could bring down the AppDomain after a certain inactivity on the application. Or after certain CPU or memory usage thresholds are reached. If you want to be able to reliable store something in the ASP.NET session you could offload the storage off-proc and store this session either in a dedicated session server or SQL. But honestly, I have seen many people moving ASP.NET Session to SQL Server and regretting it. What's the point? You already have this information in SQL Server :-) I once used this and regretted it so much.
Personally I never use ASP.NET Session in my applications. If you need to persist such information as the display name and avoid hitting the database at each request you could store it in the User Data section of the Forms Authentication cookie. So here's the idea: when the user successfully inputs correct credentials, you manually create a FormsAuthenticationTicket and populate its UserData property with whatever information you want to be available about this use on each request and then emit the authentication cookie. Then you write a custom Authorize attribute in which you decrypt the cookie, fetch the User Data and store it as a custom IIdentity making it available on each request.
Store usernames in cache (Cache[string.Format("DisplayName_{0}", User.Id)] = User.Username), cookies or move session to SQL Server instead of InProc
I would create a static helper method that gets username by user id. If it finds cached value, it will use that, if not, get value from db, store it in cache and return.
public static string GetUsername(int UserID)
{
string cacheKey=string.Format("DisplayName_{0}", UserID);
if (HttpContext.Current.Cache[cacheKey]==null)
{
// Retrieve user name from DB
string Username=Repository.GetUserName(UserID);
HttpContext.Current.Cache[cacheKey]=Username;
}
return HttpContext.Current.Cache[cacheKey].ToString();
}
There are better ways, but to address your specific issue your auth timeout and session timeout are not the same, you need to handle the case specifically when one will timeout before the other. See my post here:
How can I handle forms authentication timeout exceptions in ASP.NET?

When are cookies are preferable than sessions?

public class ServletDemo extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
Cookie cookie = new Cookie("url","mkyong dot com");
cookie.setMaxAge(60*60); //1 hour
response.addCookie(cookie);
pw.println("Cookies created");
}
}
I am seeing Java Cookies concept .
There is a lot of stuff on cookies , use it when small data needs to be stored on client side.
But could you please tell me , when should we use Cookies exactly ??
And when cookies are preferable than sessions ??
This one part of a whole set of design decisions relating to where we need to keep state information when several computers are involved in a system.
When you say "session" I suspect that you mean the HttpSession that servlet containers will manage for you. It's actually quite likely that the HttpSession is actually maintained by using a cookie: the cookie just holds some kind of a key to a table of sessions.
This pattern of passing some kind of reduced amount of data back to the browser and having the server keep track of the main stuff is also pretty common. Sometimes folks use all three: cookie for, say, the small stuff, HttpSession as a convenient cache, and the database for stuff they really care about.
There's lots of factors to consider, here's a few:
How much data is it reasonable to send in a cookie, too much things are going to go slow.
How secure is this? Servers often assemble lots more data then the user entered in this session, how confident are we that something sensitive can't be hijacked or read if we send it back to the browser in a cookie?
How reliable is our choice of session mechanism? Lose the browser, lose that 5k holiday booking we were just about to buy? Lose the HttpSession on the server? Perhaps the same outcome? (Some app servers have session replication, but it's an overhead).
Personally, I find that usually the HttpSession API is so convenient that I never choose to use cookies. My rule of thumb is "if it's readily re-creatable keep it in the HttpSession, otherwise make sure it's persisted in a database, if necessary creating a database specifically for state management (and not forgetting the housekeeping of that database).
Examples of re-creatable things: Items retrieved from a database (we can always get them again), things that the user would not mind re-entering (say a few search criteria). Example of non-re-creatable: the 17 page completed insurance application form.
Cookies are less secure than sessions.
A session is fully-controlled by the server. In both cases the client needs to securely present authentic session data, but with cookies there are more opportunities to sneak a look at what's going on internally. The consequences of cookie theft are in general worse then the theft of an opaque session ID.
Cookies can be faster to develop with because the server doesn't have set up session databases and the like, but they're a lower-quality solution if you care about design.
To answer your specific question, cookies are preferable to sessions when cookies can do what you can't do with sessions. I see two reasons to use them:
when you need some information about the client, and this information must keep existing across multiple client sessions, even if the user closes his browser. For example, an automatic login uses cookies: at the first request of a client session, the cookie is sent, and the web site is thus able to identify the user.
when you need to share some information between information between several web applications, provided their are all served from the same domain. For example, single sign-on can use cookies. The first application authenticates the user and sets a token cookie, which is sent to the second application. the second application may then use this cookie to automatically authenticate the user.

Problem with Sessions in ASP .NET

I have a weird issue with session variables. I'm storing some credentials in sessions variables like this:
Session["login"] = "foo";
Session["password"] = "oof";
The page is deployed on a certain server. After I logged in on the page, I noticed that other users (who are in the same network area) calling the page were logged in as well! I thought those data would be stored only for me (I suppose the server sends me back some cookies to ensure that) but that's not the case?
I certainly have a lack of knowledge somewhere. What's going on?
Thanks
I wouldn't recommend storing a password in a session variable for security purposes. If you must use a session variable, do not store the password in clear text. Use some encryption method instead.
Check your web.config
http://msdn.microsoft.com/en-us/library/h6bb9cz9.aspx

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