programmatically logout a "specific" user - asp.net

Is it possible in Asp.NET MVC to proframmatically logout a user? I am aware that you can use:
FormsService.SignOut();
But this refers to the context of the webpage making the request. I'm trying to prevent a user logging in twice. So if I call:
MembershipUser membershipUser = Membership.GetUser(userName);
if (membershipUser.IsOnline == true)
{
// log this user out so we can log them in again
FormsService.SignOut();
}
Calling FormsService.SignOut(); has no bearing on the context of the user say, with another webbrowser who is logged in already?

One common method to accomplish this goal is to, on each page load, check whether the current user needs to be signed out.
if (User.Identity.IsAuthenticated && UserNeedsToSignOut())
{
FormsAuthentication.SignOut(); // kill the authentication cookie:
Response.Redirect("~/default.aspx"); // make sure you redirect in order for the cookie to not be sent on subsequent request
}
You may be concerned that this method will be too slow,
"Why do I have to call this damned function each page load? It probably hits the database each time!"
It doesn't need to be slow. You may cache a list of users that should not be signed in at any given time. If their username is in that cache, then the sign out code will be triggered next time they access a page.

Take a look at this blog How to allow only one user per account in ASP.Net

Related

asp.net login control - remember me

When the user uses the "remember Me" option in the login control, it obviously stores a cookie somewhere and the log in gets automated.
Unfortunately I use the login controls "Logged In" event to set up other objects. When the user goes in with the Remember Me function they can bypass this event.
Is there another event i cat catch?
Failing that, is there a safe way to query the membership system to see who is logged in at any time? then i can test myself.
Thanks
You can work with User.Identity.Name
if (Request.Cookies["myCookie"] != null)
{
HttpCookie cookie = Request.Cookies.Get("myCookie");
String UserName = cookie.Values["username"];
this.Login1.RememberMeSet = !(String.IsNullOrEmpty(UserName));
}
I think you can create an HTTP Handler or use Application Events to check if user is authenticated and set up other objects
I don't think you can find any other membership event after LoggedIn , however you can get events from Page Life Cycle.
I suppose you must be redirecting to some default page after successful log in. You can try following code to get the loggedin user name if login was success.
User.Identity.Name

ASP.NET Membership: safe user delete

I am the administrator and I need to delete a user.
If the user is authenticated at the moment I delete it, what is the best strategy to force the deleted user to logout at the next request?
Must I handle this operation in the Application_AuthenticateRequest event?
In other words, can be an idea to verify in the AuthenticateRequest event if the user still exists and, if not, to delete all the cookies and redirect to logon page?
After some research and evaluation, finally I have found a strategy to handle this scenario, so, in Global.asax:
protected void Application_AuthenticateRequest()
{
var user = HttpContext.Current.User;
if (user != null)
{
if (Membership.GetUser(user.Identity.Name, true) == null)
{
CookieHelper.Clear();
Response.RedirectToRoute("Login");
}
}
}
When the request is authenticated, we verify that the user still exists in the system, if not all the cookies will be deleted and the request will be redirected to the login page.
If you delete them, then I'm assuming their next request would most likely error out for them.
Even if they have the authentication cookie, any page that checks the database against their UserID would obviously throw an exception.
You can most likely just disable the user instead of having to delete them.

How can I log any login operation in case of "Remember Me" option?

I have an asp.net login web form that have ( username textBox - password textBox ) plus Remember Me CheckBox option
When user login i do the below code
if (provider.ValidateUser(username, password))
{
int timeOut = 0x13;
DateTime expireDate = DateTime.Now.AddMinutes(19.0);
if (rememberMeCheckBox.Checked)
{
timeOut = 0x80520;
expireDate = DateTime.Now.AddYears(1);
}
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(username, true, timeOut);
string cookieValue = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue);
cookie.Expires = expireDate;
HttpContext.Current.Response.Cookies.Add(cookie);
AddForLogin(username);
Response.Redirect("...");
}
as in code after user is authenticated i log that he login in db by calling method AddForLogin(username);
But if user choose remember me in login and then he try to go to site any time this login method isn't executed as it use cookies ... so i have many questions:
1- Is this the best way to log login operation or is there any other better ?
2- In my case how to log login operation in case of remember me chosen by user ?
The best way to implement login operation is to implement your login design.It seems in your code,you're using built-in functionality plus logging custom information.
In order to log login information you can customize your Provider.Indeed there will be some db changes around,but you can handle them by stored procedures with no change in entire code.For example,create a new table that holds as many information as you wish including login operation(i mean how user is logged in,is it first time or is user already chosen remember me option so that user logged in by cookie)
Best Regards
Myra
Currently you do not have enough info to distinguish the two cases. I think that the easiest way to do what you want would be to add a temp cookie when the user logs in and then in you page class, if the temp cookie is not present, then they are using the remember me option. Then you can log this and set the temp cookie.
What I ended up doing in one application I used was test in Session_Start() if they were logged in, and do the logging there. I found that this did capture people whose login was successful due to their login cookie still being valid (so they didn't need to explicitly log in)
You'll have to test what effect this has on regular log ins to assure you aren't logging them twice, but that's simple enough to figure out. My app actually excludes logging logins when the last login was within 5 minutes, but that's just to limit how many records are there, too.
Here's my opinion after read through all the other answers.
Below is my idea with performance consideration in mind:
Create a login logging interval settings, say 12 hours or 24 hours (your choice). You can store this settings in web.config appSettings. The smaller the value, the higher performance hit.
When users login successfully at the login page manually, log it to your datastore and set a cookie with the current datetime (Last logged login datetime).
Whenever users make a page request, compare the difference between the last logged login datetime stored in the cookie and the current request datetime. If the difference is less than the interval specified in the settings, do not log it. If it is larger, refresh the cookie value to the current datetime and log the login to your datastore. This step is to reduce performance hit.
If I understand what you are hoping to accomplish, maybe FormsAuthentication_OnAuthenticate in your application class (global.asax.cs) would be the right place to log the login?

Restricting log in for each user to a single computer in ASP.NET

Looking for a robust and efficient implementation where I can restrict a user to only log in to my web app from a single computer.
If a the same user is already logged in and another person tries to log in from another computer then I should either have the option to
end the session of the currently logged in user, or
show a message to the new person trying to log in with the same user account.
Currently authentication is done using Forms Authentication with custom membership and role providers.
Our server is showing it's age so I'm looking for something that uses the least processing power and hopefully does very few db reads (if at all needed). My initial naive implementation is to store the IP (in db? app state?) on a successful login and then check on each page request or each other log in attempt depending on scenario. Would like to hear of better ideas =)
You can do it this way:
Store the current Session Id (HttpContext.Current.Session.SessionID) in the Application object, along with a time stamp.
At the next request (e.g. in Global.asax), check if the current session is the same as before and if less than 20 minutes have passed. If the session is the same, let them work normally. If they are different, only let them work if 20 minutes have passed. Do update the Application object.
This will allow one user at a time, on one computer at a time. It is probably not 100% safe, but it is a very viable way to do it.
Earlier i got a similar situation, and followed the below appraoch
Along with login name maintain a session id and timestamp in each request.
And allow the user to gain access only if both login & session id combination are same.
If the combination differs,you can either
log off the first logged in user (by
showing notification to them
saying the some other user logged into your
account ) 0r
log off the newly enterd user saying already this
account is in use
you can use timestamp of the request to validate the session timeouts..
Hi
It's the way I've implemented this (I've added these lines to onload of my Page's base class):
bool authenticated = UserIsAuthenticated();
if (Session["~~~loginprocessed"] == null)
{
if (authenticated)
{
// user just logged in:
if (Application[Page.User.Identity.Name] != null)
Application.Remove(Page.User.Identity.Name);
Application.Add(Page.User.Identity.Name, Session.SessionID);
Session.Add("~~~loginprocessed", true);
}
}
else
{
if (!authenticated)
{
Session.Remove("~~~loginprocessed");
}
}
if (authenticated)
{
if ((Application[Page.User.Identity.Name] == null) || (Application[Page.User.Identity.Name].ToString() != Session.SessionID))
{
System.Web.Security.FormsAuthentication.SignOut();
// show some message to user which will tell he has signed out because of login from somewhere else!
}
}
If I understand your question correctly, you wish to make sure each user can only be logged on once at a given time. As far as I know the ASP.NET Membership provider only stores the last activity date and the last login date. You could keep a list of user id's that are logged in and display your message when a new user tries to login as a user that is already in that list. A complication would be that you need to remove the user from this 'LoggedOn' list when he logs out. You can perhaps use session_end in Global.asax

Avoid losing PostBack user input after Auth Session has timed out in ASP.NET

I have a form that sits behind ASP.NET forms authentication. So far, the implementation follows a typical "out of the box" type configuration.
One page allows users to post messages. If the user sits on that page for a long time to compose the message, it may run past the auth session expiration. In that case, the post does not get recorded... they are just redirected to the login page.
What approach should I take to prevent the frustrating event of a long message being lost?
Obviously I could just make the auth session really long, but there are other factors in the system which discourage that approach. Is there a way I could make an exception for this particular page so that it will never redirect to the Login so long as its a postback?
My coworker came up with a general solution to this kind of problem using an HttpModule.
Keep in mind he decided to to handle his own authentication in this particular application.
Here goes:
He created an HttpModule that detected when a user was no longer logged in. If the user was no longer logged in he took the ViewState of that page along with all the form variables and stored it into a collection. After that the user gets redirected to the login page with the form variables of the previous page and the ViewState information encoded in a hidden field.
After the user successfully reauthenticates, there is a check for the hidden field. If that hidden field is available, a HTML form is populated with the old post's form variables and viewstate. Javascript was then used auto submit this form to the server.
See this related question, where the answers are all pretty much themes on the same concept of keeping values around after login:
Login page POSTS username, password, and previous POST variables to referring page. Referring page logs in user and performs action.
Login page writes out the form variables and Javascript submits to the referring page after successful login
AJAX login
If you don't care if they're logged in or not when they POST (seems a little iffy security-wise to me...) then hooking HttpContext.PostAuthenticateRequest in an IHttpModule would give you a chance to relogin using FormsAuthentication.SetAuthCookie. The FormsAuthenticationModule.Authenticate event could be used similarly by setting an HttpContext.User:
// Global.asax
void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) {
// check for postback somehow
if (Request.Url == "MyPage.aspx" && Request.Form["MySuperSecret"] == "123") {
e.User = new GenericPrincipal(new GenericIdentity(), new string[] { });
}
}
When the session timeout happens the user's session (and page information) get disposed, which would mean the eventual postback would fail. As the others have suggested there are some work arounds, but they all assume you don't care about authentication and security on that particular page.
I would recommend using Ajax to post back silently every 10 mins or so to keep it alive, or increase the timeout of the session as you suggest. You could try to make a page specific section in your web config and include in there a longer timeout.
I handled this once by adding the form value to the database, identified by the remote IP instead of user ID.
( HttpContext.Request.UserHostAddress )
Then, after login, you can check to see if the current user's IP address has a row in the database, and perform the required action.
Michael

Resources