I am reviewing some web code and I am not exactly sure how ASP.net session state works. Any helps would be gratefully appreciated.
If a User object is saved to the session state during login, and User.FirstName and User.LastName is set. If other web pages retrieve the user object from the session and set the FirstName to something else is that persisted on other web pages? Or, do you need to re-add the user object back to the session once it has been modified? Thanks
Session is persisted on the server, but tracked via the client. I repeat - via the client.
In most cases, sessions are tracked with cookies. So using your example, when User object is saved to Session:
Session["UserInfo"] = new User { FirstName = "Joe", LastName = "Bloggs" };
A cookie will be sent to the client with a unique identifier. This cookie is passed along to all further HTTP requests from this client/browser unless it expires.
If another user comes along (from a different machine) for the first time, Session["UserInfo"] will be null.
An alternative to cookies is "cookieless-session" - where instead of using a cookie to store the session identifer - the identifier is tacked onto the URL.
So the answer is no - other web pages (e.g other clients/machines/browsers) will not have access to this information.
If you want information shared between different clients from the web server, use Cache.
However given the context of the question (User information), it is valid to store this information in the Session, as it is only relevant to a particular user (shouldn't be shared).
An alternative a lot of people use instead of sticking the User info in the session, is to put it in a generic principle which get's attached to the Forms Authentication ticket.
Up to you which road you choose.
This should help you get your head around Sessions in ASP.Net
http://www.codeproject.com/KB/aspnet/ExploringSession.aspx
http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net
Any changes you make to the object are persisted.
Related
Normally I would handle a logged in user by setting a session after a successful login. That session is then checked on each request to ensure it exists.
But was about if I disabled a user account and they were currently logged in? In that case, the user would still have access to the system until their session expired.
Currently, I am pulling the account information from the database on every request and checking the status field. I feel this is a lot of unnecessary overhead. In my scenario, there are accounts and users within those accounts. Therefore, I'm having to check the account status as well as the user status on each request.
Is there a better way? Note that I'm using SQL Server Session State as this a multi-server environment.
Thanks in advance.
Store the session ID's in the database on session start. When you disable a user just remove the value in the user session id field in your database.
Check if the session id matches the stored session id in your database on requests.
If not, session.abandon().
When you disable a user account, why not remove any sessions associated with the account. Then we user accesses the server, the session will no longer exist and user will not have access.
You can use cookies ! Cookies are most powerful light weight data
storage ! store encrypted username information & state(active/deactive)
into cookies.
Instead of storing the data on each request, after the first request, you can implement a method like AuthenticationManager.IsAuthorized("user name"). This method should return two values:
True/False (If it's authorized or not, respectively).
Reason as an enumeration: UserBlocked, Timeout, ...
Thus, you'll be checking if the session is still valid on every request and the user data will be retrieved once per session start.
You can use Anonymous Identification if enabled with in your Application:
<anonymousIdentification enabled="true"/>
and you can get it like:
string strId = Request.AnonymousID;
where default it's Guid.
AnonymousId is unique for each user and you will keep track of your users as they IsAuthenticated or not.
I need to store a list of user's friends so I can use it in every page (without the need to make a database query every time).
I thought about SessionState but I think this is gonna be heavy, since the database is huge.
So I need to know if using FormsAuthenticationTicket is the right way to do it? Or should I use HttpOnly Cookies too?
FormsAuthenticationTicket
You can store custom data in a FormsAuthenticationTicket in the following manner:
string userData = "john smith;jane doe;bill murray";
HttpCookie cookie = FormsAuthentication.GetAuthCookie(user.UserName, true);
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
// Create a new FormsAuthenticationTicket that includes the custom user data
var newTicket = new FormsAuthenticationTicket(ticket.Version,
ticket.Name,
ticket.IssueDate,
ticket.Expiration,
true,
userData);
However I would be very carefull about what kind of data you include in the cookie. There are security issues for one thing and if you store too much data in it then you risk creating an invalid cookie. Plus cookies are sent to the server on each request. This will only increase the size of the request.
IIRC there is a 4KB size limit (maximum cookie size). So the amount of data which you can store in the cookie is certainly limited. And because the forms authentication cookie already contains data besides the user data and is encrypted your available storage limit is even lower.
I would only use it for very small pieces of information that I need upon each request. Certainly not data that can grow such as a list of friends. Rather identifiers, that I can use on the server to look something up. Even when the cookie is decryped these values are meaningless.
Session State
I would not store such data on the user's pc. This way this data will be distributed accross every PC / browser that he uses. If you want to avoid database roundtrips, then this would be a prime candidate for caching.
Honestly, I would store the list of friends in the session state. When the logger logs in, retrieve the list of friends once and store it in the session. When the list of friends is updated, just update the session data. Each subsequenct request can then retrieve the user's list of friends from the session state.
But apparently you don't want to store it in the session? Might be a good time to investigate if your session state provider can be changed. For example using an AppFabric cache cluster to store the session state. This way it scales more easily than the default InProc or StateServer modes.
You could give the data an expiration of an hour for example. After this timeout the list of friends is invalidated and no longer available in the session. You need to retrieve an (updated) list from the database once more. However, this way you only execute a query once every hour.
But surely storing a simple list of friends in the session state cannot not be that big of a problem. What else are you storing in it? Surely not the entire database.
You can try to store into the Cache object with SqlDependency.
For example, you are caching the result of following query (it is a simple one, I'm sure SqlDependecy would like it) and also you can create the friends "graph" from it.
select u.UserId, u.FirstName, u.LastName, f.FriendId
from Users u
left join Friends f on f.UserId = u.UserId
If you are changing the friends list, delete an user, etc, then the cache is invalidated and you don't need to worry from where you change it, from a separate application like an admin/cms or from Management Studio.
So, basically you are having a single graph of friends in the Application memory which is accessed very fast by every user from theirs sessions.
Managing the data from a cookie can be very hard to do, actually I can't image how you will be sure that the list of the friends from a cookie is the same as the one in the database.
How can I remember a user that is logged in without having a security issue? Currently, I am storing the id and a guid into two different cookies and compare them when there is no session alive. If it match then I re-create the session. Btw, both id and guid are nore encrypted.
Is this method safe enough, or should I follow a rather distinct way?
Since cookies can be easily stolen by use of XSS, does not matter if you place information in just one cookie or two, because a theft will take them all.
I have solved with a more complex procedure: I place one encrypted cookie divided in 2 parts (but 2 cookies will work as well), one fixed and the other variable each session. Both are saved also on server side to check: they are only session identifiers, no sensible information contained in the cookie, the correspondence with the user id is saved on the server.
If a fake user enters the account with a stolen cookie, the variable part (or cookie) will change, so when real user connects again he will not be able to enter and you will have the proof that an unauthorized access occurred: then you can delete the permanent session on server side (defined by the fixed part or cookie) in order to avoid any further access by the theft. The real user will re-login and create a new permanent session with a new cookie. You can also warn him that you saw a security flaw, suggesting him to reset password (operation that should never be accessible directly from cookie) or to use another browser for unsafe navigation.
If you save additional user information (user-agent, IP by location) you can check cookie validity also on them in order to avoid even the first entrance of the fake user.
I would recommend you using forms authentication for tracking logged in users in an ASP.NET application.
In my web application I am using sessions for storing the user specific data for persisting the data in between the postbacks.
I would like to know the difference between storing the data in sessions as
Session["selectedItem"] = somevalue;
and
Session["UserName"]["SelectedItem"] = somevalue;
where I have a session named Session["UserName"] which stores the name of the user who is logged in.
If i just go into more depth lets say if there are 2 users one logs into firefox and other internet explorer, will there be any conflict if i store the value in the first way meaning the session data is overwritten or shared, and this conflict would be resolved if i use sessions in second way.
Is there any noticeable difference in the way session variable is stored between these 2 session implementations or are they just identical ?
Data stored in a session is, per definition, stored against a specific user - and it will work regardless of whether your user has been authenticated or not (if your user is anonymous the server will still set a cookie in the user's browser with a unique id for the user's session).
The session object provides a simple one-dimensional collection for storing data, meaning that you can only store data in the session by providing a single key, e.g.
Session["myKey"] = myObject;
Of course, if myObject is an array or another collection then you can reference elements within myObject like this:
Session["myKey"][0];
Session["myKey"]["anotherKey"];
Sessions are unique per user, so there's no need to key your Session variables by user.
The session is generally tied to a particular browser through cookies and is isolated from other sessions.
Hope following points clear your doubts
You will get a new session/session ID when using different browsers
If you are using the same browser (tabs or multiple instances) and your session is set to use cookies, by default cookies will be shared among all tabs and/or instances of a browser
If you want a different session when using the same browser you will need to use cookieless sessions.
What is the difference between a Session and a Cookie?
What circumstances should each be used?
Sessions
Sessions are stored per-user in memory(or an alternative Session-State) on the server. Sessions use a cookie(session key) to tie the user to the session. This means no "sensitive" data is stored in the cookie on the users machine.
Sessions are generally used to maintain state when you navigate through a website. However, they can also be used to hold commonly accessed objects. Only if the Session-state is set to InProc, if set to another Session-State mode the object must also serializable.
Session["userName"] = "EvilBoy";
if(Session["userName"] != null)
lblUserName.Text = Session["userName"].ToString();
Cookies
Cookies are stored per-user on the users machine. A cookie is usually just a bit of information. Cookies are usually used for simple user settings colours preferences ect. No sensitive information should ever be stored in a cookie.
You can never fully trust that a cookie has not been tampered with by a user or outside source however if security is a big concern and you must use cookies then you can either encrypt your cookies or set them to only be transmitted over SSL. A user can clear his cookies at any time or not allow cookies altogether so you cannot count on them being there just because a user has visited your site in the past.
//add a username Cookie
Response.Cookies["userName"].Value = "EvilBoy";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(10);
//Can Limit a cookie to a certain Domain
Response.Cookies["userName"].Domain = "Stackoverflow.com";
//request a username cookie
if(Request.Cookies["userName"] != null)
lblUserName.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);
sidenote
It is worth mentioning that ASP.NET also supports cookieless state-management
Cookie is a client side storage of your variables. It stored on client machine by browser physically. It's scope is machine wide. Different users at same machine can read same cookie.
Because of this :
You should not store sensitive data on cookie.
You should not store data that belongs to one user account.
Cookie has no effect on server resources.
Cookie expires at specified date by you.
Session is a server side storage of your variables. Default, it stored on server's memory. But you can configure it to store at SqlServer. It's scope is browser wide. Same user can run two or more browsers and each browser has it's own session.
Because of this :
You can save sensitive data in session.
You should not save everything in session. it's waste of server resources.
After user closes browser, session timeout clears all information. (default is 20 minutes)
A cookie is an identifaction string stored by a server (who has a domain) in the browser of the user who visits the server/domain.
A session is a unit of maybe variables, state, settings while a certain user is accessing a server/domain in a specific time frame. All the session information is in the traditional model stored on the server (!)
Because many concurrent users can visit a server/domain at the same time the server needs to be able to distinguish many different concurrent sessions and always assign the right session to the right user. (And no user may "steal" another uses's session)
This is done through the cookie. The cookie which is stored in the browser and which should in this case be a random combination like s73jsd74df4fdf (so it cannot be guessed) is sent on each request from the browser to the server, and the server can assign and use the correct session for its answers (page views)
The cookie allows the server to recognize the browser/user. The session allows the server to remember information between different page views.
Sessions are not reliant on the user allowing a cookie. They work instead like a token allowing access and passing information while the user has their browser open. The problem with sessions is that when you close your browser you also lose the session. So, if you had a site requiring a login, this couldn't be saved as a session like it could as a cookie, and the user would be forced to re-login every time they visit.
Its possible to have both: a database primary key is hashed and stored in a lookup table: then the hash is stored on the client as a cookie. Once the hash cookie (hahhahaha :) is submitted, its corresponding primary key is looked up, and the rest of the details are associated with it in another table on the server database.
The main difference between cookies and sessions is that cookies are stored in the user's browser, and sessions are not. This difference determines what each is best used for.
A cookie can keep information in the user's browser until deleted. If a person has a login and password, this can be set as a cookie in their browser so they do not have to re-login to your website every time they visit. You can store almost anything in a browser cookie.
Session is a server side object,
which transfer or access data between page call.
Cookies is a object which is client side/client machine which store some text information of browser and server.
There appears to be some confusion regarding what a session cookie is.
Firstly, when we are talking session cookies - it has nothing to do with ASP.Net sessions. Likewise, session cookies have nothing to do with server side processes or caching.
A session cookie is nothing more than a cookie that expires when the browser session expires. To create a session cookie - don't put an expiration date on it. Doing this stores the cookie in memory and is disposed of when the browser is disposed.