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
Related
I have a login control supporting "Remember Me" option.
The Markup
<asp:Login ID="UsersLogin" runat="server" OnAuthenticate="UsersLogin_Authenticate" DisplayRememberMe="true"
CssClass="usersLogin" FailureText="The username or password you supplied is incorrect"
Width="100%">
</asp:Login>
The Code-behind:
protected void UsersLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
Page.Validate(); // Executes the validation controls against the input controls.
if (!Page.IsValid) return; // Return from the function, incase validation fails.
e.Authenticated = Membership.ValidateUser(UsersLogin.UserName, UsersLogin.Password);
FormsAuthentication.RedirectFromLoginPage(UsersLogin.UserName, UsersLogin.RememberMeSet);
}
Steps performed and my observations (might be incorrect):
1). User enters the credentials and checks the "Remember Me" check box. ASP.NET will create a persistent cookie on the client side.
2). ASP.NET then navigates the user to some protected resource as indicated by "returnUrl" query string parameter, if available. Otherwise it will redirect the user to the page as specified in the "DefaultUrl" property of tag in web.config.
3). User closes the browser.
4). User reopens the browser, and types the url to the same protected resource. ASP.NET will grant access to that protected resource, because of the persistent cookie.
5). Now user navigates to the login page. ASP.NET should populate the username and password text box and also check the "Remember Me" check box.
The step 5 is where I am stuck. I'm not sure whether its the responsibility of ASP.NET to ensure step 5.
I'm aware this problem has been asked many a times, but I haven't found a reasonable solution, as many were just workarounds. Some solution suggested to create your own FormsAuthenticationTicket and add UserData to store the remember Me status. Rest suggested to explicitly write down the tag in web.config and explicitly specifying every parameter including timeout, path etc.
Also correct me on this statement:
"ASP.NET will delete the persistent cookie if we log out from the application, either by clicking the "LoginStatus" control or by having a normal link button and writing
"FormsAuthentication.Log();
FormsAuthentication.RedirectToLoginPage()"
on the click of normal link button".
Please advice, what needs to be done so that I can make the login control check the Remember Me checked.
Thanks in advance.
I think I have found the solution. This is what I did to get the check box checked.
if (User.Identity.IsAuthenticated)
{
FormsIdentity identity = User.Identity as FormsIdentity;
FormsAuthenticationTicket ticket = identity.Ticket;
if (ticket.IsPersistent)
{
UsersLogin.RememberMeSet = true;
}
}
If the user had checked the Remember Me check box, the ticket would be a persistent ticket.
Thanks anyways.
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?
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
I have an ASP.NET login control on a page, with the "Remember Me" checkbox displayed. I have checked in trace and the authentication cookie is being created, I have sliding expiration set and a timeout of 60000, yet when I return to the website the login is not being remembered.
Any ideas where else I can check?
Thanks,
Darryl
Correct! The Remember Me checkbox doesn't do anything for you and why should it?
After succesful login; you could create the cookie from code and (when entering the page or masterpage or whatever) attempt to read the previously made cookie to get your credentials.
Or you could use the SetAuthCookie when using FormsAuthentication; reference: http://msdn.microsoft.com/en-us/library/sxb3b282(vs.71).aspx
I've found that whenever any problems are potentially related to cookies, that Firecookie is an invaluable tool for finding out what is actually going on...
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