No Multiple Login on Same machine but same browser allowed - asp.net

I have a simple requirement of not allowing a user to log into multiple browsers at a time. Same browser is fine.
What is the simplest thing which can be done?
Technlogy : .net 4.0 and sql sever 2008 R2

See my advices below:
Store LastActivityDate for each user. If you are using asp.net SqlMembershipProvider - this field exists there, if you use another authentication mechanisms - probably you need to create it and update with each request of certain user.
Add an additional boolean field LoggedIn for each user. This field will be set to true when user does login. If you are using asp.net SqlMembershipProvider you can store its value in Comment field.
When user closes the browser send request to server to 'logout' user, which means set LoggedIn field to false. Use window.onbeforeunload javascript event for that.
On user login you should check LoggedIn field for the user, if it is false - you simply process the operation. If not - you should check LastActivityDate value, and if it older than a timeout you will define (lets say 3 minutes) process the operation. If not - reject it and show error message. This additinal check is required because we cannot guarantee that window.onbeforeunload is always executed.
The final step would be a javascript which consequentially calls a server action in timeout which updates LastActivityDate. This script should be defined on each page which is accessible for logged in user.
I hope the approach is clear.

Related

asp.net identity 2 require particular claim to log in

In MVC5 asp.net - Is there a way to allow user login only if the user has a particular claim in the user database? I'd like to assign a "CanLogin" claim to users in my user database that are allowed to log in at any given time. By removing the "CanLogin" claim, I could effectively lock the users out of the system until further notice.
This would have to work for a first time login as well as cookie login at a later stage if the user has checked "remember my login".
Using authentication filter, you can check the identity.claims property to validate whatever claims are present in the context.
The claims must be added during the login process
Then you can check whether a particular user is enabled or not.
However, if the user database is self maintained, you can just set a disabled flag and then reject the login request, instead of returning such a claim.
The claims are used for Authorization to a particular functionality rather than Authentication to an app. A valid user will have certain claims which can tell what all the user is permitted to do.

Asp.net How to update sql table column if unexpectedly PC was shutdown

Scenario: I am working on website in which user login and do some tasks and logout. When user login in website I put a true value in database so other user is not logged in with the same username and password.
Problem: Above scenario was working fine. But I a face problem when unexpectedly PC was shutdown and that true value is there which I put in database on the first time when user login in my website. And the first user is unable to again logged in from same PC.
What I want: I need a mechanism in asp.net in which When unexpectedly PC was restarted / shutdown server automatically update my column in sql.
You can't use server code to monitor client machine behavior.
I suggest you re-design the database with a expiring time session, which will handle the login event when "true" value is on but user try to login again.
Another the way could be allowing users to "unlock" themselves, by email-reset token, or by secret password.
When user login in website I put a true value in database so other
user is not logged in with the same username and password.
It is not a good design, because internet is not reliable. You are very closed; instead of Boolean value in database, you want to store a token.
Solution
You need to redesign the system based on cookie (or you can also use bearer token).
When a user login, create a new token and store it in both database and cookie.
When a user request a page, validate submitted cookie with the one in database. If they are not same, ask the user to re-login again.
I need a mechanism in asp.net in which When unexpectedly PC was restarted / shutdown server automatically update my column in sql.
SignalR can help. On your website you have a HUB, that hub can detect when users connect or disconnect. Just map when disconnect is called and set that user in the database to false.
I agree with previous comments that it's a poor design. But SignalR can work around that for you.
http://www.asp.net/signalr

ASP.Net MVC3 FormsAuthentication overall logged-in event

I have an ASP.Net MVC3 app. When the LogIn action is called, I use the MembershipProvider to validate the user and FormsAuthentication to set the cookie.
Additionally, I get some info about the user from a database and store it in Session.
When the user subsequently visits the site, they're already authenticated via the cookie, and I'm looking for somewhere to hook into so I can fetch the info about the user from the database again.
Is HttpApplication.AuthorizeRequest() the best place to do this? Obviously this is called for every request so I was hoping there was something I could use that just indicated the user had been authenticated - either explicitly after logging in or when they're authenticated automatically.
There are several events that get triggered on every request, HttpApplication.AuthorizeRequest() should work.
In order to only fetch from the database for logged in users, you can check the Name property of User.Identity which only gets set once the user authenticates:
if(!string.IsEmpty(User.Identity.Name))
{
//make call to database
}

the latest logon session is retained and the user is automatically signed out from the other session

Let suppose, I am building an asp.net website which has login scenario in it. I want to provide a certain functionality to the website that if the user is already login on computer 1 and now try to login on computer 2, so he will be allowed to remain login on computer 2, while automatically logout him from computer 1.
I also know that http is a stateless medium, so whenever user interact with computer 1 and try to interact with the page, it will get noticed at that time.
You need to store the additional data (the computer currently 'logged in') in the database, or application state. Then when you process the authentication request - check to see if the machine you stored matches the one requesting authentication - if it does not, you would force the user to log-in and store the new computer (ip address) in the database/application state.
In case Tony's suggestion does not fulfill your purpose, You need to generate a hash comprising of "UserLoginName" + "HOST_NAME" +"TIME" (or any combination you like) and store that hash in your Database against that loginName and also send that hash to the user in a Cookie.
On subsequent request you can check through a handler or module if that specific cookie is submitted and contains the value matching your database, if it matches then the user is coming from the same machine and no need to update anything , if not user is coming from some other machine either the cookie shall not be there or would be containing some other hash value so you should send him to Login page again and upon login just recreate the hash and update it in your database against his login.
Hope this shall work.

Event to capture when a formsauthenticated user is un-authenticated

I'm basically looking for the event that is the opposite of FormsAuthentication_OnAuthenticate. I want to remove some values from the database when a user logs out. I tried putting it into the Session_End event, but it seems that the user is already gone by the time this executes.
Update:
If I can't determine when a specific user is deauthenticated (ie, due to session timeout) then is there a way to get a list of all currently authenticated users? If I could, then in the Session_End I could just remove the records from the DB that are not associated with a currently authenticated users.
Session_End isn't guarenteed to fire - if you're not using InProc sessions for example, then it won't fire at all. If your application recycles or dies, again, it won't fire.
Your best bet would be to have this code in a shared method that you can call from numerous places:
In your LoginStatus control you can set the LoggingOut event - call your method there to handle people who log out sensibly.
If you're using InProc sessions, in your Session_End event, but make sure you check to see if they are logged out already (as you've seen).
If you're not using InProc sessions, you'll need to get a little more creative. Perhaps look at having an event that fires every now and then (perhaps on Session_Start which does fire regardless) that goes through and clears out those users who's last active time is older than the session timeout (as mentioned by Greg).
Unforunately the Membership class gives you some useful details, but not all of them:
GetNumberOfUsersOnline
This will "Gets the number of users currently accessing an application." - great, but the only methods that will get users either:
GetAllUsers // Gets all the users from the storage provider (can be paged)
FindUsersByName
FindUsersByEmail
Sadly none of these have a property to only return "active users" as per the count.
Looking at the members of MembershipUser there isn't a "IsOnline" property - only LastLogonDate and LastActivtyDate - due to the disconnected nature of the web, this is probably as good as you're going to get.
I would imagine you have them logging out via the click of a button or link or something like that. Why not just put the code in that same event / block. Near where you put the FormsAuthentication.SignOut() call.
There is a Session_End handler in the Global.asax in which you could put could that you want to execute when the session expires.
I am not sure that this is what you want though. Session and authentication are two different things. If your authentication technique is providing a FormsAuthenticationTicket to the user (inside a cookie) and that ticket has an expiration, well the expiration of the authentication is controlled via this ticket. It will not be actively managed on the server. Each request the user makes the ticket is provided and the server then determines if the user is still authenticated.
Bottom line is, you can detect when the user's session expires, but you probably won't be able to determine when their authentication expires, unless both expiration values are identical.
If you're using the SQL provider, the aspnet_Users table has a "LastActivityDate" column. If you compare that to the timeout value of forms authentication, you could come up with a list of users are definitely not logged in. Your count would be low if they log out manually with a "log out" link.

Resources