Best practices for using HTTP sessions
- Enable Security integration for securing HTTP sessions
HTTP sessions are identified by session IDs. A session ID is a pseudo-random number generated at the runtime. Session hijacking is a known attack HTTP sessions and can be prevented if all the requests going over the network are enforced to be over a secure connection (meaning, HTTPS). But not every configuration in a customer environment enforces this constraint because of the performance impact of SSL connections. Due to this relaxed mode, HTTP session is vulnerable to hijacking and because of this vulnerability, WebSphere Application Server has the option to tightly integrate HTTP sessions and WAS security. Enable security in WAS so that the sessions are protected in a manner that only users who created the sessions are allowed to access them.
- Release HttpSession objects using javax.servlet.http.HttpSession.invalidate() when finished.
HttpSession objects live inside the web container until:
- The application explicitly and programmatically releases it using the javax.servlet.http.HttpSession.invalidate method; quite often, programmatic invalidation is part of an application logout function.
- WAS destroys the allocated HttpSession when it expires (default = 1800 seconds or 30 minutes). The WAS can only maintain a certain number of HTTP sessions in memory based on session management settings. In case of distributed sessions, when maximum cache limit is reached in memory, the session management facility removes the least recently used (LRU) one from cache to make room for a session.
- Avoid trying to save and reuse the HttpSession object outside of each servlet or JSP file.
The HttpSession object is a function of the HttpRequest (we can get it only through the req.getSession method), and a copy of it is valid only for the life of the service method of the servlet or JSP file. We cannot cache the HttpSession object and refer to it outside the scope of a servlet or JSP file.
- Implement the java.io.Serializable interface when developing new objects to be stored in the HTTP session.
Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Implementing the java.io.Serializable interface allows the object to properly serialize when using distributed sessions. Classes that do not implement this interface will not have their states serialized or deserialized. Therefore, if a class does not implement the Serializable interface, the JVM cannot persist its state into a database or into another JVM. All subtypes of a serializable class are serializable. An example of this follows:
public class MyObject implements java.io.Serializable {...}
Make sure all instance variable objects that are not marked transient are serializable. We cannot cache a non-serializable object.
In compliance with the Java Servlet specification, the distributed servlet container must create an IllegalArgumentException for objects when the container cannot support the mechanism necessary for migration of the session storing them. An exception is created only when we have selected distributable.
- Use <codeph>write frequency=END_OF_SERVICE</codeph> when enabling session state failover to avoid losing data during failover with either database or WebSphere eXtreme Scale. Data loss is avoided because session data is stored to the database or data grid at the end of each request. This behavior results in longer request times, which degrades performance.
- Ensure the Java objects we add to a session are in the correct class path.
If we add Java objects to a session, place the class files for those objects in the correct class path (the application class path if utilizing sharing across web modules in an enterprise application, or the web module class path if using the Servlet 2.2-compliant session sharing) or in the directory containing other servlets used in WAS. In the case of session clustering, this action applies to every node in the cluster.
Because the HttpSession object is shared among servlets that the user might access, consider adopting a site-wide naming convention to avoid conflicts.
- Avoid storing large object graphs in the HttpSession object.
In most applications each servlet only requires a fraction of the total session data. However, by storing the data in the HttpSession object as one large object, an application forces WAS to process all of it each time.
- Use Session Affinity to help achieve higher cache hits in the WAS.
WAS has functionality in the HTTP Server plug-in to help with session affinity. The plug-in reads the cookie data (or encoded URL) from the browser and helps direct the request to the appropriate application or clone based on the assigned session key. This functionality increases use of the in-memory cache and reduces hits to the database or another WAS instance
We can use Firefox Browser Developer to track cookies and inspect HTML.
- Maximize use of session affinity and avoid breaking affinity.
Use session affinity properly can enhance the performance of the WAS. Session affinity in the WAS environment is a way to maximize the in-memory cache of session objects and reduce the amount of reads to the database or another WAS instance. Session affinity works by caching the session objects in the server instance of the application with which a user is interacting. If the application is deployed in multiple servers of a server group, the application can direct the user to any one of the servers. If the users starts on server1 and then comes in on server2 a little later, the server must write all of the session information to the external location so that the server instance in which server2 is running can read the database. We can avoid this database read using session affinity. With session affinity, the user starts on server1 for the first request; then for every successive request, the user is directed back to server1. Server1 has to look only at the cache to get the session information; server1 never has to make a call to the session database to get the information.
We can improve performance by not breaking session affinity. Some suggestions to help avoid breaking session affinity are:
- Combine all web applications into a single application server instance, if possible, and use modeling or cloning to provide failover support.
- Create the session for the frame page, but do not create sessions for the pages within the frame when using multi-frame JSP files. (See discussion later in this topic.)
- When using multi-framed pages, follow these guidelines:
- Create a session in only one frame or before accessing any frame sets. For example, assuming there is no session already associated with the browser and a user accesses a multi-framed JSP file, the browser issues concurrent requests for the JSP files. Because the requests are not part of any session, the JSP files end up creating multiple sessions and all of the cookies are sent back to the browser. The browser honors only the last cookie that arrives. Therefore, only the client can retrieve the session associated with the last cookie. Creating a session before accessing multi-framed pages that utilize JSP files is recommended.
- By default, JSP files get a HTTPSession using request.getSession(true) method. So by default JSP files create a new session if none exists for the client. Each JSP page in the browser is requesting a new session, but only one session is used per browser instance. A developer can use...
<% @ page session="false" %>
...to turn off the automatic session creation from the JSP files that do not access the session. Then if the page needs access to the session information, the developer can use...
<%HttpSession session = javax.servlet.http.HttpServletRequest.getSession(false); %>
to get the already existing session created by the original session creating JSP file. This action helps prevent breaking session affinity on the initial loading of the frame pages.
- Update session data using only one frame. When using framesets, requests come into the HTTP server concurrently. Modifying session data within only one frame so that session changes are not overwritten by session changes in concurrent frameset is recommended.
- Avoid using multi-framed JSP files where the frames point to different web applications. This action results in losing the session created by another web application because the JSESSIONID cookie from the first web application gets overwritten by the JSESSIONID created by the second web application.
- Secure all of the pages (not just some) when applying security to servlets or JSP files that use sessions with security integration enabled, .
When it comes to security and sessions, it is all or nothing. It does not make sense to protect access to session state only part of the time. When security integration is enabled in the session management facility, all resources from which a session is created or accessed must be either secured or unsecured. We cannot mix secured and unsecured resources.
The problem with securing only a couple of pages is that sessions created in secured pages are created under the identity of the authenticated user. Only the same user can access sessions in other secured pages. To protect these sessions from use by unauthorized users, we cannot access these sessions from an unsecured page. When a request from an unsecured page occurs, access is denied and an UnauthorizedSessionRequestException error is created. (UnauthorizedSessionRequestException is a runtime exception; it is logged for you.)
- Use manual update and either the sync() method or time-based write in applications that read session data, and update infrequently.
With END_OF_SERVICE as write frequency, when an application uses sessions and anytime data is read from or written to that session, the LastAccess time field updates. If database sessions are used, a new write to the database is produced. This activity is a performance hit that we can avoid using the Manual Update option and having the record written back to the database only when data values update, not on every read or write of the record.
To use manual update, turn it on in the session management service. (See the previous tables for location information.) Additionally, the application code must use the com.ibm.websphere.servlet.session.IBMSession class instead of the generic HttpSession. Within the IBMSession object there is a sync method. This method tells the WAS to write the data in the session object to the database. This activity helps the developer to improve overall performance by having the session information persist only when necessary.
An alternative to using the manual updates is to utilize the timed updates to persist data at different time intervals. This action provides similar results as the manual update scheme.
- Implement the following suggestions to achieve high performance:
- If the applications do not change the session data frequently, use Manual Update and the sync function (or timed interval update) to efficiently persist session information.
- Keep the amount of data stored in the session as small as possible. With the ease of using sessions to hold data, sometimes too much data is stored in the session objects. Determine a proper balance of data storage and performance to effectively use sessions.
- If using database sessions, use a dedicated database for the session database. Avoid using the application database. This helps to avoid contention for JDBC connections and allows for better database performance.
- If using memory-to-memory sessions, employ partitioning (either group or single replica) as your clusters grow in size and scaling decreases.
- Verify that we have the latest fix packs for the WAS.
- Use the following tools to help monitor session performance.
- Run the com.ibm.servlet.personalization.sessiontracking.IBMTrackerDebug servlet. - To run this servlet, we must have the servlet invoker running in the web application we want to run this from. Or, we can explicitly configure this servlet in the application we want to run.
- Use the WAS Resource Analyzer which comes with WAS to monitor active sessions and statistics for the WAS environment.
- Use database tracking tools such as "Monitoring" in DB2 . (See the respective documentation for the database system used.)
Related:
Sessions Task overview: Managing HTTP sessions