What is an active session in a Java web application? - java

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

Related

jsessionid is saved and used even after reboot\re-installation of the service

I have a Tomcat 7 web server.
After login to it I can see under Cookies that there is jsessionid which, from what I have read is saving the id of the session instance between the user and the web server.
But the thing I cannot understand is that after I login and I stay in the browser.
I can stop the server, even un install it from the system and re-install it.
and then after I restart it I can continue navigating in the website without needing to enter credentials or anything like that, as if nothing happened in the background - I just can move on with the same jesssionId.
So basically I will divide my question into sub-question so it will be easier to answer:
1. How is it even possible that after stopping the service or even un install it it can still happen?
2. How excatly is the jesessionID created? I mean is it possible that it is the same jsession id?
3.When exactly does the jsessionID is being created?
4. Is it possible to change this behavior and "invalidate" the session so the user will have to re-enter his credentials?
5. Following question #4, what is common in most of the services? demand to login again or to enable the use of the old session id ?
Thanks a lot!
In answer to your questions:
Tomcat's session Manager will serialize session data and save it to a file to persist it across restarts. You can disable this.
Tomcat's SessionId Generator determines the exact way the id is created.
Here a good answer for when session ids are created: Under what conditions is a JSESSIONID created?
If your goal is to invalidate sessions after a Tomcat restart, you can do this by disabling session persistence.
Typically a user would want to be considered "logged in" until they click a "log out" link or button in your application. You can also adjust the session expiration time if you want the session to expire after a period of inactivity. How exactly this should work is up to you and depends on your application's use cases.

Session Invalidated in JBOSS clustered environment with load balancer and sticky session

We are facing one issue in a Struts application deployed in JBOSS clustered environment with load balancer and sticky session
Issue description
1) This issue happens in a user registration functionality which has 2 pages, register1.do and register2.do page
2) When user clicks on registration url, https://ourwebsite.com/register1.do
Two GET request are made
GET register1.do (Gets 1st registration page and sets few values in session)
GET captcha.do (This loads a captcha image to be shown on register1.do)
3) Sometimes what happens is GET request to register1.do sets a JSESSIONID cookie and the GET request to captcha.do over write JSESSIONID cookie set by first request. This causes problem in 2nd registration page as it fetches some of the values stored in session and as the session is overwritten by captcha no values can be obtained.
see below image
4) This scenario does not happen every time, once this issue occurs and if we go back to register1.do page a refresh(F5)/hard refresh (Ctrl + F5) then GET request to captcha.do does not over write JSESSIONID cookie and user registration works fine.
Moreover this happens only in clustered environment, in single JBOSS environment it works fine.
Can anyone please help me to identify what could be possible problem
here ?
Why session does not get over written when we do a page refresh ?
Update your apache mod_cluster binaries to mod_cluster 1.2.6.Final which are available here.
This solved it for me, which was jumping servers after every single refresh. Hopefully that helps.
I also experienced the same problem with jboss eap 6.1 and in load balancer i'm going with mod_cluster configuration I changed algorithm from server per session to entry per session and sticky session is working well and good .Go through the following to know about entry per session and server per session.
Entry-per-Session means that the device creates additional client-table entries whenever a source IP opens a new session (unique source port). This gives the unit more accurate tracking of the number of sessions, but it's behavior is to continue sending all the traffic from the client's source IP to the same server.
In Server-per-Session mode, the device tracks the unique source ports the same way, but when the client opens a new session, the device makes a new load-balancing decision for the new session. This way multiple sessions from the same client IP can be 'sprayed' among all the servers rather than being stuck to a single server.

some questions/mystery about browser session and session Id?

As per my understanding same session is shared among different tabs of same browser window. And for different browser window , different session
is created. Now some questions on my understanding:-
1)When i hit my web application in two different browser window, i see same jsession id on firefox console. How same session session is
shared among two different browser window. As by default session is maintained through cookies with the help of jsessionId which is created
by webserver. Other way of maintaining the session thru URLRewriting where we maintain session by passing jsessionId in each url request.
I can see using org.tuckey.web.filters.urlrewrite.UrlRewriteFilter in project but this class document does not seem to do any magic much session maintenance.
I am not getting how come same session is attached with two different browser window and techinical approach to do it
2)similary when i hit two different application under two different tabs of same browser window
probably google and some other website say yahoo, i dont see same jsessionId in firefox console for these two website. Is the website
doing some special stuff here to generate new session for each Tab? In fact for some website(probably for google) i do not see jsessionId at
all under firefox window. How its possible. My understanding it is generated automatically by webserver and is passed either by
cookies or URLReWriting?
It would be helpful if somebody can answer inline to my question as its important to understand each point posted here for session management
UPDATE:- Let me put my questions with different scenarios:-
1)Hit two different URL(say google.com and stackoverflow.com) in two different tab of same browser window.
My Understanding:- Two session will be created as two cookies will be created for two different domain/port
2)Hit two same URL(say stackoverflow.com) in two different tab of same browser window.
My Understanding:- Onesession will be created as same cookies will be reused
3)Hit two same URL(say stackoverflow.com) in two totally different window of browser (firefox).
My Understanding:- how many session will be created in this case?
Your first assumption is not correct. If you use session management with cookies (default for Java servlet containers) then your session is visible in all windows of the same browser instance.
If you configure your Java servlet server to use URL rewrite only for sessions, then you can have one session per tab.
Usually two different Java web applications will always create two different session cookies only valid for its own application scope. The cookies are bound to the domain and path.
Other web frameworks like PHP can handle this totally different.
The cookie jsession_id is created by the server, which sends it to the browser in return for a request through a HTTP header Set-Cookie . The cookie is stored on the client by the browser. Henceforth, the browser will resend that cookie for every subsequent request on the same domain (the cookie can be restrained with secure and path https://en.wikipedia.org/wiki/HTTP_cookie#Terminology but it is irrelevant here).
The browser has access to that cookie from all tabs (basic rights and security) and it is a design choice if it separates sessions (same cookies on all tabs) or merges them (same cookies on all tabs, therefore same session on all tabs within the same domain). As far as I know, all browsers choose to share cookies on tabs but I am no expert.
So in order to maintain session on multiple instances of the same java program, you need to do the same and store your jsession_id cookie (and reuse it if relevant) outside of the memory of each instance (for example on file). This might not be trivial if security is important.
As to point 2, it is important to understand that even though both cookies are jsession_id, they are related to different domains (and have been set by each server) so there is no reason for them to be equal.

Why remember me token?

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.

How can I manage sessions in Java EE?

In my Java EE application, I have a problem with sessions. Different users can login to the application and the specified user can see the data for which he is authorized. He should not be able to see other user data. To differentiate users, we are using Client_ID. As soon as the user logs in we are fetching this Client_ID from the database and setting it in session like this:
session.setAttribute("Client_ID",user.getClient_ID())
We access this session value throughout the application and fetching the relevant data to that Client_ID. This works fine when users work on a single browser, but the problem is this:
Suppose there is a SuperAdmin, who needs to look all the clients under him. SuperAdmin logs in as client_1, and again as client_2. SuperAdmin has logged in both times using the same browser. When I refresh the client_1 browser, I am seeing the client_2 details, which should not happen.
I think our application is using the same session for two different logins in the same browser. What would be solution for this problem? I should see the correct data for the particular client when I refresh the page.
Don't use cookies for storing Session ID, but use request parameter instead.
So each opened tab will request the own session. With cookies you have only one cookie for all tabs in browser.
P.S.:
I think that it's incorrect to log in under 2 or more users within one browser at the same moment. Your application should detect that client_1 is already signed it and restict log in for other users from the same browser until logout. For example, Google's applications work in such way.
Also would be great if SuperAdmin have a feature to see client_1 or client_2 data without log in. This will save him/her from remembering dozens of passwords and will increase performance of work (time is moneys, isn't?).
If you want multiple tabs within the same browser instance to see different things, then you will have to rework your session management and key things off of the URL.
The session is shared between browser tabs (true for most browsers), so logging in with one tab will affect the sessions for other tabs.
The solution is to use roles instead of multiple logins. You would give client_1 SuperAdmin role, and client 2 doesn't. This would reduce the need to login twice.
But in any case, you should only allow one user to be logged in at once. The process of logging in should invalidate the previous session. I forget the exact code in Java EE, but it is something like session.invalidate().

Categories