I have a table called Eventlog, this table contains already data about user connection: when the user calls this action for example :
public ActionResult Login(string username, string password)
{
}
I test whether the user already exists on database or not
If yes, I use Session["user"] = username or
FormsAuthentication.SetAuthCookie(username, true); to set the user
session
And then I put a record on the Eventlog table : user X was connected at Y o'clock
This works fine, but I want also the information about the user logging out. I can do similar thing to the LogOff Action, I guess it is gonna work fine as well, but the majority of people don't use the logoff button, they only close the browser, how is it possible to implement the user logoff event for this situation when the user closes the browser: user X has been disconnected at Y o'clock. The Session_End() does not serve the need in this situation.
You have to accept the limitations of web technology. Once you have sent your response to the user agent, the server has no way to know what is happening with the request. The user might close the user agent gracefully. The UA might crash. The user might lose internet connection. His computer can crash. All of this can happen before the client even receives the response. This is the environment you are dealing with. Embrace it instead of fighting it.
If tracking logoff is important to you, there are several techniques you might use:
Rely on the session timeout. If you choose a timeout short enough it might be enough to meet your security requirements. I would consider this the preferred way, because it is simple and proven.
Use scripting to send a heartbeat from the UA to the server. You can use "ping" requests, long calls etc. However, be aware of the performance impact this comes with, the number of requests to the server and the complexity of the implementation.
Use an existing framework such as SignalR to establish a client-to-server connection and have the client check in to the server. This is basically the second option with less manual work for you.
All of this wouldn't let you intercept user logoff or loss of connection, but if the client stops responding you know that the connection is interrupted (in one of many possible ways). So you shouldn't register this as "user logged off", but rather as "user disconnected".
How is it possible to implement that ? checking every 1hour if the SessionId exists or not #Mehdi
If you do a post the last time the user does a new action with something like:
if(Session["UserName"] != null) {
/*Update the database with the last time that the user has performed a action*/
}
If you do every time the user goes to a new action, you will get the last time the user did something that has inpact on the server. Then you know the (not exact but a indicator) last time the user wasn't logged off.
It's not possible on the server side to know when a user closes the browser. However, you can use JavaScript to trigger on the window.close and send an AJAX call to the server, therefore recording when a user leaves. This is unreliable, however, since the user has control over browser settings, and could disable JS. It's probably the best you can do.
Related
Are there some method to prevent multi-device login using Playfab?
I have a card game with Playfab authentication. I must have a login control for cheaters, I would like to have only one login for each player and for each of their device, if a user login with a new device, the old device must be logged out automatically.
I try to change the session ticket or entity ticket at runtime in my c# code but I read in another post that Playfab is designed for multi-device login, in fact there isn't any function to change the session or entity ticket.
I saw somebody using CloudScript, but I don't know how it works and I don't know if it is heavy to do this.
A possible option could be to execute a custom cloudscript function on game startup to save on Player Data the current deviceId. Every request will have to be validated using this "token", so client will have to pass this kind of information at every call.
If deviceId matches with the one saved on server, execution continues smoothly, otherwise an error should be passed as response to the client. This error can be used to show a popup on client to inform user for example.
At every login, deviceId is updated on PlayerData. In this way, you know it is read on every request, but written only once (on game startup). Also, only the last logged will be able to get server data. Other devices won't be able to get proper responses from server until the app is rebooted.
Situation:
I have an application where our domain users can register their domain account via an Active Directory interface. They can then unlock their account or reset their password via this application. These two "functionalities", the registration/administration & the unlock/reset, take place on different servers. The whole process of unlocking or resetting uses two-factor authentication via a token app on the mobile phone. The only way to link the token to the app is by scanning a QR code (or typewriting the code) which is shown in the registration process. So far so good.
Now it can happen that we have to reset the mobile phone of a user completely, for example for sending it to repair. Even with a backup, the data in the token app cannot be restored. So far, the only possibility to get the QR code back, is to completely delete the registration in our service and re-register again, thereby generating a new QR code. The process of registration takes a while, as you have to think of several security questions (and answers). This is not very user-friendly.
My task now is to implement a function that allows you to show the QR code. This page can be accessed from the "administration" page each user has for their account. The whole site uses single sign on, which of course makes sense, as you don't want to enter the password every time you want to edit a security question for example.
Problem:
With single sign on, every person can walk up to another user's computer and if it isn't locked, show and scan their QR code, change the security questions so they know the answers, reset the victim's password and log into their account. This has to be prevented of course, as it poses a huge security risk.
My approach was to prompt the user's credentials and check whether the user is the same as via SSO by clearing IE's authentication cache via JavaScript. I use the Windows Security window for the credential validation. This way, I don't have to worry about the AD interface.
To check if it's the same user that logged in, I use a cookie with the username from SSO. Then, in the controller, I check if it's equal to User.Identity.Name. If not, I set the cookie with the username from SSO and the rest of the response:
if (cookie.Value.equals(User.Identity.Name))
{
// do some irrelevant stuff
return View();
}
else
{
Request.Cookies["cookieName"] = User.Identity.Name;
Response.AppendHeader("Connection", "close");
Response.StatusCode = 401;
Response.StatusDescription = "Unauthorized";
Response.Clear();
Response.Write("Unauthorized Access");
Response.End();
}
This works just fine. There is one problem though: If you click on cancel in the Windows Security window, you'll be redirected to a "unauthorized access" page. You can then, however, refresh the page and TADA! Single Sign On logged you in automatically and you or the attacker can therefor see the QR code.
Question:
How can I go around SSO in this specific scenario? So far I have only found solutions saying that I should turn off SSO which would affect the whole application.
Sorry
I know this is a long question, my English might not be clear in some cases and I possibly left out some information unintentionally. Feel free to ask for more information.
I need to show user log in time details.I have two table.One is UserMaster which contains UserDetails and one is UserLogInTimeDetails contains two columns UserId and LogedInTime.
When User Log in UserId and LogInTime stores in UserLogInTimeDetails.
When User Log Off I am deleting the row of that particular user from UserLogInTimeDetails.
But the problem is if an user close the browser then the details of the user in not deleted from UserLogInTimeDetails table.For which that user will not be able to log in again.
How to solve this issue?
I have googled and saw that browser close event in not possible to handle and in many places they have adviced to use onbeforeunload event which is not working for me.
Please help. I am in big trouble.
Perhaps you could get it working using Session_End in your global.asax file to remove the user when their session expires. Though I'm not 100% sure if you can get the session ID from this method. It may be within the EventArgs...
void Session_End(Object sender, EventArgs e) {
//Remove user from database here
}
Else, another way to store the data is based on last activity, so everytime the user submits a request you update the time of last activity. You could even store this with a session ID in the database along with their login time, and then be able to calculate the duration active from login time to last activity for that session;
Best way to go with this using signalR. You can track user is online or offline. based on even dispose you can track exact logout or browser close too.
Hope this will teach you something new. refer below link for a simple example of signalR.
signalR sample application for online, offline status
Is it important that the user cannot login multiple times from different browsers?
If not, a more common approach is to store a login information variable in a session variable (maybe login time, user id or something like that), and use it to verify if the user has logged in or not.
If the user close the browser the session is lost, and he must login again, but he can login as many times as he wishes from different browsers.
You can access these variables like this:
// Set it like this. Can be any type of object with login data.
Session["LoginData"] = "Hello";
// Get it like this.
string test = (string)Session["LoginData"];
Edit:
If it is important that the user must nog login multiple times, you have a much bigger problem to solve.
Maybe something like this could be the solution?
Let the browser (via ajax) ping the web server somehow, every few seconds or so (how many depends on how long you want the browser to be shut down before it is ok to login again vs. traffic)
When the server receives a ping from a certain user, stamp the date and time in a session variable.
If a browser is trying to access the web page in any way, first, check for the session and for how long time ago the last ping was done. If the session is null, or the time is more than the time between pings*2 (or something like that) the user can login again (send to login page). If the time is shorter check if the user is logged in. If he is, continue. If not, tell him he must log out from the first connection (or whatever you want).
Hope this helps!
Hi i am developing a chat application along with some other pages in my application. once i login i am maintaining the session of the user. My main intention is that user should get notification whenever another user connects to server.
The problem that i am facing is whenever i navigate to some other page in my application the connection is lost. How to stop this behaviour and continue the connection until user logs out.
I am using SignalR 2.0 in ASP.NET MVC4 project, any help??
Each connection only has a lifecycle for the duration of the time the user spends on a given page. When they navigate to another page, a new connection is established. Also, if a user has more than one tab or browser window open, they will have multiple connection Ids. I don't think you want to try to persist the connection Id beyond it's intended lifecycle.
In a similar scenario that I work on, we store the connectionIds OnConnect and delete them OnDisconnect. When a message needs to be sent to a given user, we send it to all of their connectionIds. This ensures that the message will be delivered to all tabs/windows.
EDIT 1 the following is in response to #Saurabh's comments:
Consider what the scope of the Hub is, and that of your other classes and the client. The Hub is there to facilitate communications between the browser and the server. While it's possible to do a lot of work within the hub, I think it's best to move most of the scope outside of communictions to other places.
The client knows that it just reloaded a page, so it's a good candidate for making the decision that this is a reconnect event.
_chatHub.server.reJoinRooms();
Then the Hub can query the user's rooms, by UserId, rather than ConnectionId.
public Task ReJoinRooms()
{
// get the user's rooms from your repository
// optionally get the user's connectionIds from your repository
// Clients.Caller.onJoinRooms(rooms);
// or Clients.Clients(_connectionIds).onJoinRooms(rooms);
}
Then the client can decide whether or not to take action:
$chatModule.client.onJoinRooms = function (rooms) {
for (var i in rooms) {
var _room = rooms[i];
// if I'm not already in this room, add it to my rooms
console.log('joining room', _room)
}
}
You could skin this many different ways. The client could own the scope of remembering rooms, instead of a server-side repository, too.
EDIT 2
If the number of groups/rooms that a user belongs to is ever-increasing, the above example may not scale up very well.
In that case, each user could join personal feed(s) instead (i.e. join a feed named for the user's GUID). We would keep track of each user that is affiliated with a group. When a message is sent to that group, we would iterate over those user's and publish a message to each feed.
I use the forms authentication in my asp.net application and I protect all the pages using:
deny user=*
And when a user logs in, I use:
FormsAuthentication.RedirectFromLoginPage(UserName.Text, false);
Now if I use IE6 when I open a window and login it works, but then if I open a new window ,I have to login again. It seems that a new IE6 window will open a new session or cookie (I am not sure) - how can I avoid this?
There are multiple approaches. I believe the impact for the user should be as little as possible.
You could store the last logged in, or last database action timestamp in your database. Doing so, you can verify if the last action the user had was within a number of minutes. Additionally, you could store the username ( not password ) in a cookie on the client. Next time the client opens a new session, you know the username, verify on database that the last database activity was within a number of minutes, and bypass the login obligation.
Second approach involves changing startup parameters of the clients browser, so that new windows share the session. I do not know whether this is available on all browers ( and versions ) and if you are capable of doing this.
redesign your web application so new windows don't need to be opened, unless they are from within the opened window. If they are opened from an existing, logged in window, you can send a hash key in query string, which bypasses the login procedure.
These are just a few possibilities which come to mind at this point.. If you should require more possibilities, just ask :-)
Do you mean deny user="?"? * means all users, while ? means anonymous users.