I looked around for this issue and have found two approaches: use a database table to log users logging in and remove the entry when they log out or session ends; or use Membership.GetNumberOfUsersOnline(). I tried Membership version first but when I log in it shows the number to be zero (I am using form-based authentication, using AD in in Intranet web application and using Oracle DB).
I also created a table having user's ID (what is stored as aspnet_user's username), their aspnet_user's userid, login time stamp and logout time stamp. When user logs in, I add an entry and when users logs out, I remove the entry. The problem here is if session ends and Session_End() event is called I have no way of accessing user's ID (stored in session var) in order to remove the correct entry from table.
In membership, it records certain dates when you login and create activity that update the membership user, and I think the default behavior is to use that... if you are using a custom membership provider, make sure that default behavior is preserved.
Alternatively, if you want to roll your own, to determine number of users online, everytime the user takes an action that posts back, update the time on the user record, and then create a query that checks within a relative amount of time. Session_ENd is not a perfect way to determine if a user is online or not, because it may not always fire. User's don't always click the explicit logout button too, so that may not be a good indicator as well. But since session is 20 minutes, checking where an activity occured within the last 20 minutes is a rough indicator of logged in users...
Related
I'm the new here.
I've a problem like this: I create a Register page in ASP.NET (C#) which allow to guest can register an account at my site. All user must active their account before using my website, if after 15 minutes, user doesn't active account by mail => delete that user from database, my problem is how to do it automatically?
Rather than using a timer to remove a user, I would use a more conventional approach of having an expiration time for the user (or perhaps their password). That is, when they first register, assign an expiration for 15 minutes after the present time (e.g. in a column ExpirationDate in the user table). In your authentication process, the logic should validate that the user's ID has not expired.
The problem with using a timer is that many things can go wrong. For example, if your application restarts, any active timers will be lost. It's very brittle. It's also kind of using a hammer to kill a fly. It's not necessary to ensure that someone's user record is removed immediately from the database after 15 minutes. It's only necessary to make sure they can't authenticate after that time. So make the design match the business purpose in the easiest possible way. If you really want to delete records (rather than, say, give them a chance to try again after resetting a password or something) then you can do this with some external maintenance process.
I'm currently working on Authentication and Membership system for my Web Application. It is licensed to number of users, that can be logged on in the same time.
So I come up with concept that I will make ActiveUsers table where I will store information about logged on users with their sessions' IDs.
Before new user can log in, application will check this table and will get all SIDs, then it will check whether particular session exists on server. If not it will delete record in table.
My question is: is there a way to check if session with particular ID exists on server?
Because HttpContext.Current.Session affects only current user.
There's a whole bunch of nifty events in Global.asax that you can probably use for deleting the row. Check out Session_OnEnd() for instance.
http://msdn.microsoft.com/en-us/library/ms178583.aspx
Edit: Just noticed that this really doesn't answer the question...
I am trying to find a solution to control the number of logins on asp.net application.
I need to install the application in the client server, and set the number of licences. e.g. only 10 users are allowed to access the app.
Every time someone tries to login I need to check how many user are logged in, compare with the total allowed then authorize that user to proceed.
I tried with Certificate, but I couldn't see where to match the number of logged in users with the max number of allowed user.
Also I would like to use the IP address as identifier, then if I open 3 browser windows, it count only one user logged.
Basically this web application will be sold by licences. We need to control the logins per computer, and not per user, and block logins if the limit of logins are reached.
Please forgive me, if i am not clear with the description.
Thanks for any help.
I would use the SessionID in the Session object as the key, I'd store that along with the UserID for the logged in user in a database or some kind of backing store. I'd use Session_End in the global.asax to remove the records above for any session expiring and also remove them in any logout function. You should find it fairly simple to count the number of active sessions you have and confirm that it's not the same user logging in again, if that's allowed.
What I would do is use the global.asax file and increment a counter in session_start and decrement on session_end.
Since the session is stored in a cookie, several sessions on the same computer only create one session.
Here is a good refrence for the global.asax file:
http://aspalliance.com/1114_Understanding_the_Globalasax_file.3
I would use the Membership.GetNumberOfUsersOnline method, if you are using the Membership API, to determine the number of active users.
I believe this number only counts the number of users you have authenticated so it is safe to use in your scenario.
The Setup:
Account controller with the typical logon / logoff stuff that comes baked in from the template. Not much modification here on the logon page. Using a custom membership provider (SQL), but I don't think that is impacting what I am trying to do here.
The Requirements:
The client wants to handle licensing by limiting concurrent users and not by total users. So, after referencing this post here, I set out to make this work for what I need to do. And that is to track maximum and current users for each organization that has signed up for our application. No problem, just have an application("max") and application ("current") which are both hashtables with the key being the organization id and the value being current or max users for the organization. On Session_Start, I would increment the current users, check if it exceeds max and either a) redirect to an error page or b) let them go on with what they need to do. On Session_End, I would decrement the count.
The Problem:
When using formsService.signIn, what is actually stored in session? I cannot seem to gather any information about my session in the session_start except for the session ID. So, I cannot increment the correct number for user tracking. And I cannot add a variable to session as session_start will have already fired before I get the opportunity.
The notion that session is somehow connected with authentication is a myth. They are entirely independent of each other. Session can even be shared between multiple users if they happen to share their session key; that's why you never put security-sensitive info in session. Session can also expire while you're logged in. Likewise, your session is still active after logout unless you explicitly abandon it.
Session is more like a user-specific cache.
So you need to accept this fact and adapt to it. Look and see if the current user is authenticated during session start. You'll need to increment during logon as well, since the session will have already started. Etc.
I am trying to find out in my asp.net application the users that are currently logged in the application by searching on the session info. Currently, I am only able to see my current session, but I cannot find out if there are other users using it. Is there a way to see if there are other users using the application by looking at the session information
Session state is per user - Application state (global) seems to be what you're looking for.
There are 2 hashes Session and Application, in which you can store key-value pairs.
A way to do it would be to update Application[UserNamesList] whenever there is a successful login. This would then be visible to all users. Application state would however be lost whenever the App Web Server recycles or restarts... but that shouldn't be a problem in this case.
A session is supposed to only give you information about the currently logged-in user.
If you need to keep track of all logged-in users, you could consider writing the users into a global variable. Here is info on how that works. Note that sessions expire. You would have to write, for each user, the time the user was last seen (i.e. each time they hit a new page, update their record). When the time they were last seen is greater than your session timeout, it's safe to assume they are no longer logged in and you can remove them from the list of current users. If they just up and close their browser, you will not be alerted and you will still think they are logged in even though they are not.