Keep Session in Sync with FormsAuthentication - asp.net

When a user logs in through my login page, I authenticate them using FormsAuthentication, and set some Sessions that holds user specific info, like UserID and RoleID. I set site content based on these values.
The problem is when the session expires and the user is still signed in - things are messed up, because the session is null but the user is still signed in.
How can I keep them in sync with each other, so the session only expires if they're signed out or vs.
Thank you.

When the session has ended (Session_OnEnd) in global.asax, you can kill the forms authentication cookie. Doing so will redirect the user to the default page (or login page depending on how you set it up) upon any subsequent requests. You should also kill the authentication cookie when user has manually logged out - same effect.
To kill the authentication cookie:
FormsAuthentication.SignOut();

Related

When to invalidate session

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.

Why is User.Identity.IsAuthenticated equal true after I restart my dev. server?

I think that internal mechanism of authenticaton should set a cookie with a token and store the same token on a server and next on every request compare the tokens from the cookie and on the server and if they are equal then user is logged in. I don't know where a server stores token, maybe in Session or something else (not persistent), but I'm sure that after the server's restart the server's tokens's store should be cleaned up therefore a user with an old cookie can't be authenticated. But in a practice after I restart my server a user is still authenticated and have access to pages because User.Identity.IsAuthenticated returns true. It seems to me wrong. Even if I remove this user from my DB (I use Membership) because I don't want this user have access anymore and restart my server, the user is still authenticated. Can anyone explain this?
Source of answer
Here is how authentication process works.
You setup some stuff in your web.config around where the login page is, how long the login is good for and whether or not to use sliding
expiration (should the time be extended if the user is active on your
site)
User comes to your site, enters their username and password.
That information is posted to your server. You take that information, verify that it is correct (authenticate). If it is
correct, the server then issues an encrypted cookie known as the
FormsAuthenticationTicket Note - this could have a different name in
the new Identity stuff, but the same principle.
The cookie's contents includes items such as the user name and expiration date of the login.
On each request, the server looks at the cookie collection for the authentication cookie. If found, it decrypts it, reads the values and
determines if this is still a valid cookie (expiration time). Once it
has the user information from the cookie, the server can use this
information to determine if the user is authorized for the resource
requested (look up by username).
If the cookie is not present, or has expired, or When the user logs out, the cookie is deleted from the cookie collection. Now, if the user tries to go to a resource that is for authorized users only, then the user is redirected back to the login page.
Hope this helps.

password expiration policy for already logged in users

I want to use password expiration policy. For users who want to login into the website we can check the password on authenticate event of login control. But what about users who has already logged in and won't be cached by login page. In this question, it is suggested that handling HttpApplication.PostAuthenticateRequest event that is not a good approach.
I'm thinking about handling session_start() event. For each user this fires once and we can check if user password is current or not. But I don't know if an already logged in user visits th site after some days would this event fires or not?
Are you sure you want to log users out just because the password has expired? The logon cookie expiration and password expiration are separate concerns.
I don't see anything wrong in maintaing the login cookie until it expires by itself and then forcing the user to change his/her password upon next logon. Just make sure you don't issue cookies with too long expiration period and sooner or later all your users will have to relogin. And this is where you catch possible password expiration.
Note also, that checking the expiration on each request (it doesn't matter if it is PostAuthenticate or PreHandlerExecute) could be just impossible. If your site relies on external authentication source, you just can't go there and check the password expiration. Imagine asking Google or Facebook (if your users authenticate there) whether the password expired or not. It is just not easily possible (or not possible at all).

How do I let a user know that his/her session has expired?

I have set Tomcat to dispose of sessions after 15 minutes of inactivity. Something like this
<session-config>
<session-timeout>15</session-timeout>
</session-config>
Whenever a user accesses a restricted page (one that requires a user to be logged in) I check the session to see if the login process has been completed. If it has then access is granted if it hasn't then the user is redirected to the login page where he/she is prompted with a valid ID and a password. If a session times out then the user is required to log in again. And this is fine, but I would like to let the user know that he/she has to logi in again because the session has timed out.
How do I go about doing this? I found the HttpSessionListener interface and thought it might help but the sessionDestroyed method is called right before the session is invalidated so setting a parameter there is no good, as expected.
On login, set a long living cookie (1 day?) which you remove (set age to 0) during a normal logout. If you land at the login page again while the user is not logged in and the cookie is still present, then it means that the session has been expired.
<c:if test="${empty user && not empty cookie.user}">
You were logged out because the session was expired.
</c:if>
When you redirect the user to the login form, set a request parameter, url parameter, or cookie that indicates that the session has expired (erase the cookie once you've displayed the login form if you use a cookie). Then, when displaying the form, check for the session expired indicator and show an appropriate message.
You can check if the session has expired and/or timed out with:
if (request.getRequestedSessionId() != null
&& !request.isRequestedSessionIdValid()) {
// Session is expired
}
Use getRequestedSessionId to distinguish between new and existing (valid/expired) sessions, and use isRequestedSessionIdValid to distinguish betwheen valid and new/expired sessions.
You can put this code in a Filter.

ASP.Net Session Not Invalidated After Logout

I have a ASP.Net application in my login page I call
FormsAuthentication.SignOut
Session.Abandon()
Session.Clear()
however the Appscan is taking the ASPXAUTH cookie value then after logout is able to re-inject the cookie value to gain access to protected pages.
Microsoft has acknowledged a problem but only offers advice not a fix - http://support.microsoft.com/kb/900111
Can someone provide examples how to fix this issue
One option is to have a UserSession table and insert a record into this table when the user logs in. When you logout either delete the entry or mark it invalid. On the secure pages, verify that a UserSession exists for the logged in user and redirect to a login page if it does not.
set a session value on login, clear it on log out and check it on each access to a secure page. The session value is not sent to the client and as such the client/attacker can not manipulate it.
walkthrough without session value cleared on exit :
user visits login page - generates viewstate
man-in-the-middle-hacker collects viewstate
user submits login form - generates auth cookies
man-in-the-middle-hacker collects auth cookies
user logs out - server clears users cookies
man-in-the-middle-hacker continues to use previous credentials completely unhindered
game over
walkthrough wit session value cleared on exit :
user visits login page - generates viewstate
man-in-the-middle-hacker collects viewstate
user submits login form - generates auth cookies
man-in-the-middle-hacker collects auth cookies
user logs out - server clears users cookies and sets its internal session flag value to null
man-in-the-middle-hacker continues to use previous credentials but because the session he is working with now has the value null server redirects to login page.
win!

Resources