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.
Related
Is it possible to allow only one concurrent login per user in ASP.NET web application?
I am working on a web application in which I want to make sure that the website allows only one login per user at a time. How to check that the current user already logged in or not?
Please suggest proper login method by which we can handle this problem. I think we should use SQL Server session state to handle this problem. What do you suggest?
I thought of one solution for it. We can do something like:
When the user logs into the system then we insert session id in user column. (We will use database session so that we can get all session related data like isexpired, expiredatetime etc easily).
When the same user tries to login a second time then we will check for that session id column and check that session is already expired or not. If session is not expired then we will not allow user to login.
Update user session ID every time when user logs out.
Please suggest whether this is the proper way or not.
Please refer to:
When the same user ID is trying to log in on multiple devices, how do I kill the session on the other device?
Out of the box, .NET does not support this. .NET allows for concurrent log-ins, as I'm sure you're aware.
I had this same exact requirement, and came up with a pretty slick solution, demonstrated in the link above. In a nutshell, my requirement was to only have one user log-in happening at one time. If that same user ID tried to log in elsewhere, then it killed the session for the first log-in by checking for an existing log-in under a different Session ID (this enabled the user ID to be logged in from multiple instances of their web browser on their computer [same Session ID], which is common, but not from a different computer [different Session ID] (possibly due to someone that stole their credentials, for example)). Through modification of the code you could probably change the behavior of this - i.e., prevent the second log-in attempt instead of killing the first log-in that's already active and in use.
Of course, it may not fit 100% to what you're needing, so feel free to modify it to fit your needs.
You can create a cache entry per user and store their session ID in it. Session ID will be unique per browser session. In your login page, you can create that cache entry when they successfully login:
if(Cache.ContainsKey["Login_" + username])
// Handle "Another session exists" case here
else
Cache.Add("Login_" + username, this.Session.SessionID);
(Code typed in textbox without syntax check. Assume "pseudo-code".)
In global.asax you can then hook into the Session_End and expire that cache entry of the user. See this for the global.asax events.
if(Cache.ContainsKey["Login_" + username])
Cache.Remove("Login_" + username);
You could add a flag column in the user table that indicates that a user is currently logged in.
When a users attempts to log in you check the flag if it's true (that users account is already currently used) then you don't allow the new user to log in, if the flag is false the users is allowed to log in as there account is not being used by anyone else at this time.
Be aware though that unless the uses actively logs out, you cannot know when the users moves on to something else (goes to different website or closes the browser, etc.) so you need to set some kind of session timeout that will automatically log out the user if there are no new requests within a specified time period.
This means that if a users closes his/her browser and try to log in on a mobile device for example, he/she will be unable to log in until your specified session timeout runs out, so give the timeout a bit of thought as you don't want the user to get logged out to quickly (if he/she is reading a long page, etc.) and you don't want the users to be unable to log in on another device for hours if he/she forgot to log out before leaving the home.
The login credentials are stored on the cookie, so to know if the user is logged in you need to keep this informations on server, prefered on a database because the database can be the only common place among web garden or web farm.
What you can keep, is on a table, that the user A is logged in or not, flag it that is logged out, maybe last user interaction to have a timeout, etc...
So let say that the User A, is logged in, then you open a flag on the database for that user, that is now logged in, and if is try to logged again, you keep him out.
To make this work you need to either say to your users to log out, or to keep a time out, similar to the time out of the credentials.
If You are using identity system this link will help you how to single user login on multiple device.
Prevent Multiple Logins in Asp.Net Identity
I have tried they work fine in my Asp.net Mvc Project.
Solution can be this way:
Add new column in your login table GuidCode.
Step 1 : When logging in check if the GuidCode in database is null.
Step 2 : Update GuidCode by new guid and also store it in the session.
Step 3 : If it is not null then take guid from the session and compare with database GuidCode value.
Step 4 : If it is same then allow login:
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.
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.
I have an ASP.NET MVC application running on IIS7. I use sessions to keep track of logged in users. There is a session named IsSignedIn. ("true" means this user is currently logged in).
I also have an administration page for my application.
Now, say user1 who is signed in already, must be suspended from using the service immediately. So I want to invalidate the session variables set for user1 from my administration page (this will force the user to sign in again).
Is there a way I can access/modify session variables set by each logged in user from my administration page?
You can not change a session variable from another session.
One way to solve your problem is to store a list of logged in users in the Application-object, and then change the value in that variable. For this to work you must check at the top of each page that this user is in the list of logged in users.
As çağdaş commented on this answer, performance would probably be better if you store a list of users you want to log out in your application-variable. Then on the top of your page do something like this (pseudo, this actuall code snippet will not work)
if(Application["SuspendedUsers"].Contains(Session["UserID"]) {
Session["IsSignedIn"] = false;
Application["SuspendedUsers"].Remove(Session["UserID"]);
}
Where is your session state stored? If it's in SQL server, you should be able to invalidate it by updating the relevant row in the database. The standard session state server, however, doesn't appear to allow this.
Alternatively, check your database at the top of each relevant page to see if the user still has rights/is authenticated.
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.