Why remember me token? - java

While implementing the "remember me" feature for a website, why do we complicate things and have a token called remember me token apart from a session token.
To the best of my understanding, remember me token can be used to login and create a new session token while the session token only lasts for a few minutes or till the time the user closes the browser.
Why can't we increase the expiry duration of the session token itself to the desired time till which we want the user to be logged in?
I have a need to implement such a functionality in a flex based application running over tomcat and I wondering the need of remember me tokens
Also, is it possible to get this functionality out of the box within tomcat?

1) Sessions typically contain a whole bunch of data other than the user's login name. Therefore, if you just set the expiration date to a few weeks or months like a remember me token, you'd probably run into performance problems on the server due to thousands or millions of heavyweight session objects.
2) Remember tokens are client-side, not server-side. This puts all of the storage requirements on the user's browser, which is a better solution for simple data like login names. If you relied on session ID's linked to in-memory objects on the server, then every time you restart your server or the server process (to deploy an updated application, for instance), then all of those session objects would be lost.

Because by definition, a session ends as soon as the user closes his or her browser. Thus the session cookie will expire as soon as the browser is closed.
Since the purpose of remember-me functionality is to keep the user logged in across sessions, the information stored in the remember-me cookie must persist across browser restarts.
To get this functionality "out of the box" look at using a framework like Spring Security.

Remember-me cookies usually store the username and some kind of token. Both of them are used to authenticate the user. Take a look at Improved Persistent Login Cookie Best Practice which describes the process quite good.
The session cookie is used to store a session ID on the client which allows the server to recognize a session an load the session data that is associated with the session.
So remember-me cookies have a longer life time (usually days or weeks) than session cookies. Session cookies usually expire after a few minutes or when the browser is closed.
From the top of my head there are a few reasons why two different cookies are used:
If only the persistent remember-me cookie would be used the server would need to authenticate the user with every request. When an additional session cookie is used the server doesn't have to do this as long as the session is valid. Of course the session ID could be stored within the remember-me cookie, but what's the point in doing that?
From a coding point of view it's better to reuse the existing session mechanism. Why reinvent the wheel instead of just adding a feature (authentication via remember-me cookie) that can be enabled/disabled easily?

People have correctly said that the session contains a number of heavy weight objects. With enough users on your system, if you try to keep them all in the finite amount of memory that the server has, eventually you will crash the server when that memory max's out.
I worked on a project one time where a production code update had a memory leak. It was a J2EE project (yes J2EE not Java EE). When a user logged in to check their invoice at this phone company the user session was not released properly from memory (I can't remember the cause but that was definitely the issue). This bug mimics what you are asking about doing on purpose.
The server kept crashing. So we put a profiler on it. We would watch the memory use go up through the day until it topped out and shorty after the app server crashed. We added memory and increased the VM memory setting. I told them it was a memory leak but because I wasn't a $200.00/hour "server expert" people were unwilling to believe it because the people who were there still believed that the garbage collector was all powerful instead of being just very good.
Two days later (it affected the "view your invoice" system, not the main business system, i.e. it didn't have the same workload or memory requirements even though it had plenty of hardware memory in the servers), they hired a couple of $200.00 per hour consultants who after a day told them the app had the aforementioned memory leak. It was fixed and all was good... minus the consultants fees.
In any case here is the take away from this: if you don't end user sessions when users log out or close their browser (session time out), you run a real risk of maxing out your memory and crashing your servers. Especially if your site or app has any significant number of users. As mentioned by others, lightweight tokens/cookies are best.

The reason for why we should use another cookie other than the sessionId cookie to remember the user is not because sessions should expire fast or you'll face performance problems on server.
Jetty (And probably many other servlet containers) has a feature that enables automatic eviction of idle sessions from memory to disk or database which IMHO rules out all the above justifications around performance problems that comes with storing heavyweight sessions in memory.
The reason another cookie is used is that remember-me is to remember the user even after the session has expired. So if user's session has expired, the other cookie is used to authenticate the user without them having to enter a password, which obviously makes phishing attacks less likely. Although there are disadvantages to it as well, for example if someone gains access to your laptop and steals your authentication tokens would be able to impersonate you, unless the server applies even more security measures to bind the token to your client and location only.
In short, remember-me is an authentication mechanism and not a replacement for session cookies.
I believe it is fine to have long term session expiration dates as long as they are stored out of memory. And once they expire, simply ask for password. Many websites offer this feature as "Remember me for 30 days" which is achieved just by using a long term sessionId cookie, nothing else.

Related

Invalidating a Java HTTP Session to redirect to a different server, without logging the user out

I am attempting the following flow:
Invalidate the HttpSession
Load balancer redirects the user to a server
User should already be logged in, irregardless of which server they are sent to.
Notes:
Sticky sessions are enabled, but should not matter when the session is invalidated. There are existing rules that log out a user after a certain amount of time, but I need to be able ensure that the user stays logged in when a certain method that invalidates the session is called.
The servers are not clustered and so no server is aware of the other server. It is also impossible to implement Redis or similar in the current environment.
The server is JBoss 7 (EAP 6.1)
I am stuck on the logical flow, and I can't seem to find someone that has done this alread, apart from invalidating with httpSession.invalidate()
but I need to be able ensure that the user stays logged in - then why have those session timeout rules? Which is more important: security or the user experience?
More secure approach and easiest to implement: the front-end uses a timer to alert the user to inactivity a few minutes before the session expires. If the user ignores the alert, too bad. The user must log back in.
Less secure approach and harder to implement, but a better user experience: When the user logs in store a token in shared storage which is associated with the user. Each request includes the token as a header or posted value but never as query parameter so if the session expires the token can be looked up to get the trusted user, and log the user back in without a password. Of course, any session context will still be lost since the session had expired so depending on what the user was doing this could cause confusion for the user.
But how long should the token be considered valid? Suppose the session timeout is 15 minutes (which is a regulatory requirement for some apps), how long should the token be trusted? 30 minutes, 1 hour, 24 hours? It's a slippery slope.
Again, which is more important: security or the user experience?

What is an active session in a Java web application?

What are "active sessions" in tomcat? I am trying to monitor active sessions for a Java web application. But the values I am getting are not matching with number of people using web application. Could you please explain?
Basically the number of active sessions is the number of existing or previous browser or other connections with an unique jSESSIONID cookie value. As soon as someone hits your webpage with a browser a new session is initiated and an unique JSESSIONID is assigned to this session. If next hit is performed with the same JSESSIONID (which is transmitted as cookie or url parameter) the session count remains the same. If the parameter is not transmitted a new session is created.
Usually all browsers keep the session id cookie over multiple requests and even multiple tabs or windows (except for incognito tabs/windows of course).
There are multiple reasons why your session count is larger than you user count.
Sessions are held in tomcat for a period of time, with 2 hours being the default. You can change this amount in tomcat settings. So if 100 user logins into your application in first hour, and 100 in second, your total session count will be 200, even if the first 100 users are idle.
Robots like the google bot tend to create tons of sessions. If your page is publicly available check the access logs if there are some bots visiting your page.
If your application is behind the loadbalancer or proxy which are continuously 'pinging' your application for its availability, this pings can create sessions as well.
Finally there are a lot of 'funny' ways your app can get requests from browsers, for example search results prefetching and similar.
Also keep in mind that session is bound to the domain name of the site. So if a user connects to your site via multiple domains (for example www.domain.com for content and static.domain.com for images) each of the connections will have its own session.
Now, there are different way to prevent unneeded session creation, depending on what your exact problem is (and if it is a problem at all).
If you have parts of your application that don't require a session ensure that you don't call request.getSession() somewhere in your code. Also in the jsp you can explicitly turn off session with <%# page session="false" %>
The the session timeout lower to make them expire quicker in tomcat/conf/web.xml <session-config><session-timeout>30</session-timeout></session-config>
The session-timeout value is in minutes.
Finally if you are interested in what is really happening in your application, get yourself an APM (application performance management) tool like MoSKito

Workaround to share session cookie between two domains in Apache Tomcat

I have a website under a domain called www.example.com.br. And my server is set to work with cookie session tracking mode.
getServletContext().getSessionCookieConfig().setDomain(".example.com.br");
getServletContext().getSessionCookieConfig().setPath("/");
But now I'm introducing an english version of the website under www.example.com, because for Google and SEO techniques it's better to have different domains instead of a subdomain.
I found a lot of questions in Stack Overflow about this, and I know it's impossible for a lot of security reasons.
But isn't there anyway to tell Tomcat to work with a cookie domain .example.com.br if the URL has .com.br and .example.com if the URL has .com? I don't need to share session information... ie: the user may have to login again if he changes the domain. I'm not worried about it. The problem is that no information on the .com version is been stored at all, because the cookie is set to .com.br version.
Isn't there any workaround for that?
It is user's browser that decides whether to send the cookie with the request or not. Web server (Tomcat, in your case) does not have any say in that decision. What you are asking for explicitly forbidden. For example, RFC2109 says:
A user agent should make every attempt to prevent the sharing of
session information between hosts that are in different domains.
The best recommendation I can make is to make your session management (login, logout, ...) work off a single domain, regardless of what domain user originally accessed.

request.getUserPrincipal() is still not null after session is invalidated

I have web application deployed on websphere application server 7.0. User logins using /j_security_check. When session timeout occures session ivnvalidates but request.getUserPrincipal() is still not null. I expect it should be null. How to clean user principal?
I have found solution in sphere documentation.
In the administrative console, click Security > Global security.
Under Custom properties, click New.
In the Name field, enter com.ibm.ws.security.web.logoutOnHTTPSessionExpire.
In the Values field, enter true.
Click Apply and Save to save the changes to your configuration.
Resynchronize and restart the server.
In addition to solution provided by Vadim, I would like to share two links that describe a couple of alternative workarounds, and explanation of the mechanisms causing this seemingly counter intuitive mode of operation.
If you're using SSO (single sign on) between different applications, there may be a little drawback of using com.ibm.ws.security.web.logoutOnHTTPSessionExpire=true setting. This setting essentially invalidates LTPA token. Since security cache at server refreshes from LTPA token when it times out, invalidated LTPA will cause revalidation (login) of user for remaining applications [1].
Answer to Question 9 (which seems to be same as our question) at [2] provides ideas for two alternative workarounds for this problem, where you may time out authentication using servlet filters based on lifetime and inactivity.
[1]: Security Cache, LTPA Token, and Session Time Outs (requires login)
[2]: Q & A: Frequently asked questions about WebSphere Application Server security
The key thing to bear in mind is a valid/invalid HTTPSession is not the same as security.
They are completely different.
Once you are authenticated by the server, you can still have application work without any HTTPSession if you want to.
Once you are authenticatd by the server, you get a LTPA token returned to your browser and the LTPA token is active for say 2 hours (which is the default).
If your HTTP Session expires that does not affect the LTPA token if you don't to anything extra.
You could try: ibm_security_logout which would invalidate the LTPA token.
I guess with the later versions of Servlet API we do have a proper logout operation available which would eliminate the need for this.
HTH
Manglu

Spring doesn't set an AUTH cookie by default, after logging in. Why?

I am working with Flex and Spring on a project, where I need to authenticate my users to give them the chance to build their personal profiles.
On my services side I made two very simple methods login and logout, which the Flex client calls through a remote object. What I noticed, though, is that apart from the JSESSIONID cookie, Spring doesn't set any other authentication specific cookie. Thus, when I try to do something auth specific, for example logging out, or requesting data from a specific service, the server breaks my client state, because the session might have expired. However, the client doesn't know anything about that.
In fact, I don't want sessions to expire at least until I close the browser completely. The normal JSESSION expiry time is 30 mins, I think, which, if we speak about the server is completely understandable, since the server must have a reasonably timely management of the sessions (resp. threads) being open.
That's why I need a second AUTH cookie, which by default expires on browser close. However, I am also thinking f implementing something like "Remember me" which should increase the expiry date with 14 days.
BTW, I assumed that Spring Security takes care of this automatically, by setting an AUTH cookie by default, but this is not the case. I think that it at least the authentication instance with the current session, since, after I log in, all the security rules I have take place absolutely fine .... until the Jsession expires, of course.
NOTE: Whatever you propose, please have in mind that there is also an AJAX client under development, which will more or less use the same infrastructure, so the cookie solution has to apply to both.
Thanks.
See http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html.

Categories