This morning me and my co-worker went on discussion about storing auth cookie when
RememberMe = false.
MVC4 , Forms Authentocation, C#.Net, Visual Studio 2012, IIS 7.5 , InProcess Session
User LogsIn,(RememberMe = false) and Navigates to an item in the app.Default session timeOut was set 30 mins,
User Copied the URL and Closed the browser(IE9)
Opened new browser(IE9) and Pasted the Copied URL, UI redirected to loginPage.
Here I say session created in step 1 is still valid., On close of the browser , browser lost the AuthCookie.
He says that that Session is created based on browser session also. I'm bit confused.
Please let me know what actually happened.
Sorry for the bad English
RememberMe = false means the authentication cookie that was issued to the user was NOT persistent (the expiration of the cookie is set to "SESSION"). That is, the cookie is lost when the browser session ends. RememberMe = true means a persistent cookie is created and is saved across multiple browser sessions(the expiration of the cookie is set to a specific date, usually configured in web.config).
Read the documentation here
I'm assuming you're using the default Session-State Mode, which is InProc. A session generates a SessionID and this ID is stored in a cookie. This cookie is sent to the user and whilst requests are made with that cookie, the session is alive. The ID itself identifies the unique browser, which is why you can log into the same website with different accounts when you use two different browsers at the same time. However, you can't sign into different accounts from different tabs of the same browser (unless the website has specifically customised their site to support that feature).
By closing the browser, this cookie is deleted, and so the session will be ended when its timeout period has been reached. The reason you're taken to the UI page is because the new cookie you have no longer has the same session ID so, for all intents and purposes, you're a new user.
Related
This is a general question regarding web session management.
What is the best practice approach to managing session timeout?
Assume a system where a user logs in, a session is created on the server, and a token identifier is sent back to the client (via httpOnly cookie).
If the user attempts some access-based check where the session is validated, presumably it makes sense to update an expiry time on the session in the DB. Does this also mean that when this happens, we should update the expiry time on the session token cookie to match?
This seems like the most obvious solution to me, but constantly rewriting the cookie seems like a lot of overhead.
Any insight into best-practice approaches is greatly appreciated. Thanks!
How to manage session timeout to keep user logged-in, prevent he/she from accidental logout?
To keep user logged-in, it is not necessary to constantly rewrite the cookie. All you need to do is making the session token cookie's expires as Session, then as long as browser is open (client keeps using your site), the session token cookie is valid. Server does not need to know the session expires time (as there is no pre-defined session expires time any more), not mention store it in DB. After user close the browser, the session token cookie is cleared, and session is terminated (invalidated).
Normally, there will be a "session timeout" setting in server, such as session-timeout in Struts2, which kills the session if client doesn’t make any request after some time.
How to make session "validate" even if user closes the browser? That is, how to implement the "remember me for 1 week" feature?
To implement this feature, a new token cookie is used (e.g. RememberMeToken). When user login successfully (possibly enable the "Remember me" checkbox on UI), server will generate a unique random token and store it in DB (together with its expires time for security reason), make it belong to user account. This RememberMeToken cookie's expires time is pretty long (1 week for example), and will be sent back to browser together with login response.
When user close the browser and re-visit the site later (or the user is inactive for long time and the session is killed in server side), server checks session token cookie and find it's missing/invalid. At this point, RememberMeToken will be checked and compared with token stored in DB, if there is a match, server will make auto-login operation for corresponding user, and return generated session token cookie to browser. This all happens in backend, client user won't feel anything.
After 1 week since user enable the "Remember me" checkbox on UI and login, the RememberMeToken cookie is expired, and user need to login again if he/she opens browser and visit the site.
I've configured SQL Server to store session state (from here).
All I want to do is that when the user has logged into my application via browser A, I see that logged session when I visit my app from the browser B.
Right now that scenario doesn't work, I must log in one more time.
When browser B is opened (assuming it's a different browser altogether or a new instance of the same browser) a new session is created; therefore, what you see is expected behavior.
Also, I assume you mention this because you store in session some sort of key that indicates that the user has logged in successfully, correct?
If you want this behavior, you'd need to send some sort of authentication cookie with a long expiration date, you'd then read the cookie on the login page and consider the user as successfully authenticated, but keep in mind that this is a potential security risk.
I use a ASP.Net login control in a straightforward manor however I have spotted that the ASPXAUTH cookie has an expiry date of {01/01/0001 00:00:00}. Should this not get to something to prevent hacker manipulation? I am not issuing the cookie myself I am letting .Net create it.
I have run a scan on my web app and it is able to store the ASPX cookie information, go to the log out page and then go to a page without a need to login I assume using the stored cookie information.
Using the application manually I am unable to do this, it always sends me to the login page when trying to access the page.
The logout page calls FormsAuthentication.SignOut()
EDIT: Turns out this is a known problem! Who knew! http://support.microsoft.com/kb/900111
You cannot read the cookies expiration date and time. The browser uses the cookies expiration date to determine whether or not to send the cookie to the server. If a cookie has expired, the browser does not send that cookie to the server with the page request, the cookie is deleted.
If the cookie has not expired the cookie is sent to the sever sans expiration information, since this information is utilized by the browser to determine if the cookie should be sent or not. You can read the expiration date from the request, but as you have discovered it returns a date time value of zero.
Try checking the expiry date of Response.Cookies collection in the LoggedIn event. This should yield the correct expiry date of the cookie.
protected void Login1_LoggedIn(object sender, System.EventArgs e)
{
HttpCookie cookie = Response.Cookies(".ASPXAUTH");
DateTime expires = cookie.Expires;
}
See Basics of Cookies in ASP.NET for more information.
If you save the value of the cookie, log out, and then re-present that cookie to the server, it will just log you in automatically as if you had never logged out.
This is because you can also tell the .NET framework to set a persistent authentication cookie (by default you can present this option to the user with the "Remember Me?" checkbox exposed with the DisplayRememberMe property of the Login control) so the expiry date would be a value in the future.
When the user comes back to the site and their browser sends the cookie, they are automatically logged in - so the behaviour you're seeing is be design.
If you need to be more secure, the easiest thing to do is add a method to the OnLoggedIn event of the login control, and set a session value (i.e. Session.Add("HasLoggedIn", true)) that you can then check elsewhere, and if it's not true, redirect to the login page:
if (null == Session["HasLoggedIn"] || !(bool)Session["HasLoggedIn"]) {
FormsAuthentication.RedirectToLoginPage();
}
Edit to respond to comment:
Which is why you're seeing the expiry date of 01/01/0001 00:00:00 - this will be deleted at the end of your session - or when you close the browser - but there's nothing fundamentally wrong with what you're seeing - just because you're not setting a persistent cookie doesn't mean that if you send a copy of an old cookie back to the server it won't log you in with it.
As I said, if you want to ensure that users have to log in each time (or to "resolve" this issue), add a session variable that you set when the user actually logs in, and reject all requests without it.
Further edit for second comment
From Explained: Forms Authentication:
Each time a subsequent request is received after authentication, the FormsAuthenticationModule class retrieves the authentication ticket from the authentication cookie, decrypts it, computes the hash value, and compares the MAC value to help ensure that the cookie has not been tampered with. Finally, the expiration time contained inside of the forms authentication ticket is verified.
Note ASP.NET does not depend on the expiration date of the cookie because this date could be easily forged.
So the cookie has to sent back to the server before the ticket has expired.
I am creating a content management system but there is one problem. What I want to do in my website is that when a user opens the website a new sessionid is created for that user, and when the user closes the website, the sessionid is cleared. How can I can do it?
There isn't a way to detect when a user closes your site or navigates away from your site. After a given period of inactivity (default 20 min), the user's session object will expire and be automatically cleared. I suggest checking out the MSDN article on Session, which will go over your options for tweaking your application's Session.
If on the other hand you're looking to perform custom logic when a user's session begins or expires (due to inactivity), you can add a Global.asax file to your application and use the Session_Start and Session_End methods for that.
That is basically the default behaviour of sessions in ASP.NET.
When a user closes the browser, the non-persistent cookie maintaining the Session ID will be dropped. This wouldn't actually expire the session, but since no reference to it will exist anymore, it will expire automatically within the default 20 minutes. Users revisiting your site after closing the browser window would have to use a new session. (Source)
An easy solution which works independently of Asp.net is to put timestamps on your session data and delete expired entries periodically.
While working with ASP.Net Forms Authentication I came across the .ASPXAUTH cookie. I have a couple questions:
What is the purpose of this cookie?
What is the location of this cookie?
The ASPXAUTH cookie is used to determine if a user is authenticated.
As far as the location of the cookie, that depends on your browser. If you are using Firefox you can view the cookie by clicking on Tools -> Options -> Privacy. Then scroll down to the domain and expand it to see the cookie and its value. The value is encrypted using the machine key (located in the server's machine.config or web.config file) so looking at the cookie on the client won't really provide you any information. You can decrypt/view the value on the server side using:
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];//.ASPXAUTH
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
where authTicket has these fields:
The statement "ASPXAUTH is basically used to maintain ASP.NET Session State" is incorrect. ASP.NET issues an entirely different cookie, named ASP.NET_SessionId, to track session state.
Actually the .ASPXAUTH cookie does not accurately tell you when the user is truly authenticated. When the user logs out of the app, the .ASPXAUTH cookie is removed from the browser. However, if you go back to the site within a short period of time (with timeout of form auth cookie), and edit the new ASP.NET_SessionId cookie's with the following:
change "name" field from "ASP.NET_SessionId" to ".ASPXAUTH"
change "value" from 24 char sessionID to old 448 char authentication string
After refresh you will be able to assume the identity of the authenticated user without technically re-authenticating again. (again assuming you do this within the specificied timeout stored within the .ASPXAUTH encrypted auth string)
A good blog post explains the problem in more detail. A possible solution is to couple the .ASPXAUTH with the ASP session.
on Chrome Browser
1.developer tools -F12
2.locate Application tab
3.point the left pane for cookies
you will find it out if ASPXAUTH cookie for the available session on logged in applicaion