Sharing tomcat session across two contexts in the same domain - java

I need to develop 2 backend applications both running on the same parent domain, the two services will need to share the sessions (login to A means user is logged into B and same for logout).
For now, I plan to host them in same tomcat but in different contexts (2 war files) to have complete isolation (main reason being that two services will be developed by different squads and we do not want any dependency for releases and two services may also have different performance requirements in the long term).
In our current architecture only with one service, we use "Session cookie" and HttpSession to do the session management, authentication logic is in a Servlet filter.
Since the two backend apps share the same domain, I should be able to use the "same session cookie", based on my tests, I can see that browser is sending cookie to both the services.
To enable session sharing, following the answer from another question (Sharing session data between contexts in Tomcat), I tried the following in context.xml of tomcat:
<Valve className="org.apache.catalina.valves.PersistentValve"/>
<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore" directory="${catalina.base}/temp/sessions"/>
</Manager>
...
The above trick did the job for login, tomcat re-used the session from ServiceA for ServiceB.
I could also see that session was persisted on the desk (I eventually plan to move to REDIS).
But after I logout using the URL of service A (https://example.com/serviceA/logout), I'm logged out from serviceA, but I noticed that I could still access end points of serviceB and tomcat session was still there on the disk.
After I logged out specifically from serviceB https://example.com/serviceB/logout, I was properly logged out from ServiceB.
This is what, I do in the logout handling:
HttpSession session = request.getSession(false);
if (session != null) {
// Invalidate the cookies
Cookie[] cookieArray = request.getCookies();
if (cookieArray != null)
{
for (Cookie c : cookieArray) {
c.setMaxAge(0);
response.addCookie(c);
}
}
// Invalidate the session
session.invalidate();
}
I'm totally confused, am I in the right direction? How is it possible that if tomcat is sharing the same session, logout isn't propagated to the other context?

Related

what are the real effects to change JSESSIONID?

I am working on a java application using spring security.
I want to avoid the session fixation, but the session fixation solution found on the docs seem not to be working as expected... here
So, I did this on my login
final HttpSession session = request.getSession(false);
if (session != null && !session.isNew()) {
session.invalidate();
}
Works great and changes the JSESSIONID everytime I call the login page...
But once I am logged in, I can call the login page again, get another JSESSIONID and still be logged in, I can just click on the back button and come back to the logged users area.
It does change the JSESSIONID, my question is, shouldnt it have a bigger effect? like invalidate my session or log me out?
When I call the log out form it does log the user out and works as expected, I am just wondering if changing the JSESSIONID has a real effect or does nto matter.
ANy idea?
I am using security 3.2
spring's session is mapped to JSESSIONID. so if a customer would have session state beans, they would be lost after changing JSESSIONID.
even though documentation tells
Spring Security protects against this automatically by creating a new
session when a user logs in
you can explicitly set configuration for session fixation by adding this
<security:session-management session-authentication-strategy-ref="fixation" />
and defining fixation bean with SessionFixationProtectionStrategy class

How to prevent session attributes from persisting on the server?

I'm new to java web development. I have created a servlet/jsp web application that is deployed on Tomcat 7. After authentication, the user go through few page that has its own forms. The inputs are stored as session attributes and are displayed on a confirmation before log out.
For the log out, I used session.invalidate() and sendRedirect("Logout.jsp").
If I run the application again, it will return my new input, but it will also copy all the old session input.
I have disabled the session persistence and put the context cachingAllowed="false".
It seems that all the session attributes are stored in the server memory. Is this problem causes by the server configuration?
Make sure you use request.getSession(boolean b) method and not the request.getSession()
All page that should be accessible to logged in user should make a call to request.getSession(false)
If call to this method does not return any session, user should be redirected to login.
make sure your information store in session like this:
HttpSession session = request.getSession();
session.setAttribute("info", info);
when you want to remove it,you should do it like this:
HttpSession session = request.getSession();
session.removeAttribute("info");

HttpServletRequest logout on old servlet-api-2.3.jar

For legacy reasons we're using servlet-api-2.3.jar, in which HttpServletRequest not yet had the logout method. What do I do instead? We're also using an old version of Oracle's ATG, which contains a class called DynamoHttpServletRequest as well, but I don't know what to do with that either. What to try/read?
It depends on what the semantics of logging in are in your application.
Typically, this should do it unless you're doing something exotic:
request.getSession().invalidate();
I'm not familiar with Dynamo, so you may want to see if it has any specifics about session management, as some frameworks do.
And if you're using any security frameworks, you may need to clear/de-autenticate an authentication token.
atg.servlet.ServletUtil.invalidateSessionNameContext(request, atg.servlet.ServletUtil.getCurrentRequest().getSession(false));
atg.servlet.ServletUtil.invalidateSession(request, atg.servlet.ServletUtil.getCurrentRequest().getSession(false));
// Redirect, the profile is null from here on.
response.sendRedirect("login");
I encountered this problem too and found this in the ATG documentation:
Some application servers maintain a single session ID between web applications for the same client (browser), in which case the session name context ID is the current web application’s session ID. This behavior is controlled by the /atg/dynamo/
servlet/sessiontracking/GenericSessionManager.singleSessionIdPerUser property, which is set to one of the following default values in the DafEar sub-module configuration layer:
WebLogic – false <--
JBoss – true
WebSphere - true
Note: Do not change these values from their defaults.
This means that on jboss and websphere you can safely use session.invalidate() however on WebLogic you will need to use something along the lines of:
protected void forceLogout(DynamoHttpServletRequest pRequest) {
HttpSession session= pRequest.getSession(false);
if (session != null ) {
// When ATG runs on weblogic you need to ensure the parent session is invalidated
// session.invalidate() does not work.
atg.servlet.ServletUtil.invalidateSession(pRequest, session);
}
}
I hope this helps explain why.

Stateful Session Bean and HTTP Session

Is there any relationship between stateful session bean and HTTP session ?
What are the use cases where we would require a stateful session bean and what use cases requires HTTP Session.
Can i expose a stateful session bean as a restful web service ?
HTTP is a stateless protocol Which means that it is actual transport protocol between the server and the client -- is "stateless because it remembers nothing between invocationsNow First read this what is HTTPSession and what is Session Bean (keep in mind that session beans are use to maintain the data state across multiple request so mostly a session bean is a stateful session bean because it holds data across whole session)
HTTP Session
An HttpSession object can hold conversational state across multiple requests from the same client. In other words, it persists for an entire session with a specific client.
We can use it to store everything we get back from the client in all the requests the client makes during a session.
Session Bean from wiki
In the Java Platform, Enterprise Edition specifications, a Session Bean is a type of Enterprise Bean.A session bean performs operations, such as calculations or database access, for the client. Although a session bean can be transactional, it is not recoverable should a system crash occur. Session bean objects either can be stateless or can maintain conversational state across methods and transactions. If a session bean maintains state, then the EJB container manages this state if the object must be removed from memory. However, the session bean object itself must manage its own persistent data.
In Simple words
Session tracking is the process of maintaining information, or state, about Web site visitors as they move from page to page. It requires some work on the part of the Web developer since there's no built-in mechanism for it. The connection from a browser to a Web server occurs over the stateless Hypertext Transfer Protocol (HTTP) AND
SFSB's are designed for managed client state over multiple calls to the same session bean (i.e. a conversation). If you look at JBoss Seam, you will see that there is very heavy use of SFSB's for conversation context.In EJB3, there is no such thing as "stateless is better than stateful session beans". For example, one provides a service like a credit card processor (stateless) and one provides processing for a multi-screen wizard use case (stateful). In My opinion Managing state using HttpSession and stateless session beans is very difficult and problematic.
EDIT: HTTPSession is use to keep the session tracking like A user sessionFor example You want to create a Login , Logout mechanism then You must need the HTTPSession because when The user will start navigation between different pages then this HTTPsession will remember that WHO is asking for the pages otherwise it is not possible(because HTTP is a stateless protocol) Now In session you just set the session of username and password and you are checking on every page that if this session exists then show the pageNow what if , You have to send a lot of information of this user across multiple requests? In this scenario, You will set all this info in a Stateful session bean But now a days , In modern frameworks session as well as information , everything is stored in Session beans because From session bean it is easy to manage them. HTTPSession was used when we were purely on Servlet and somehow JSP technologies

Secure Coding Compliance Assessment Session state must be managed

A new corporate policy on Secure Coding was recently put into effect. The initial audit assessment tagged me deficient for:
Session state must be managed such that a session will withstand replay-attacks.
I'm not exactly sure what this statement means or why I am defecient in it. I'm developing a Java Web application and set a session as such:
session.setMaxInactiveInterval(36000);
Session state must be managed such that a session will withstand replay-attacks.
The statement is way too confusing. Rewording it would yield:
The session management framework must protect the application against replay of session IDs.
It is less confusing (hopefully), and continues to carry the same meaning as the former (again, hopefully).
Typically, if one were to implement a home-grown session management framework instead of relying on the one provided by the container for instance, then it is quite possible that the session management feature of the application would be susceptible to a replay attack.
A session replay attack would involve the scenario where the session ID is replayed back in a request, after the session has expired. A well written session management framework would recognize that the provided session ID is not a valid session ID. However, there have been instances where a vulnerable session management framework accepted the now-expired session ID, and recreated the contents of the session. In worser scenarios, the session management framework did not destroy the session at all, on session expiry, resulting in the scenario where a session ID replay resulting in requests being processed.
It must be remembered that even normal users of the application may unintentionally perform session-replay attacks, if they are able to browse to protected pages in the application without logging in. This is an indication of a failure in the authentication and the session management features of the application, for the app should ideally allow users to browse protected pages only after successful authentication, which would yield a token (a session ID) that may be used for a certain duration to access the site without further authentication. If you are using persistent cookies for authentication, you may have unintentionally introduced a hole.
Going by the above, one can protect any application from session replay attacks by:
Ensure that you are using the container provided session management features. From the use of the session.setMaxInactiveInterval I would assume that you are it. But, to be sure, verify if you are creating session IDs using other means, or for that matter, verify if you are using identifiers that are equivalent to session IDs. In simpler words, ensure that your application relies only on the value of the JSESSIONID cookie (or the equivalent as configured in the container) to communicate session IDs to the browser. Also, verify if persistent cookie are in use (refer the above posted scenario).
Invalidate the session after a certain idle period. If you do not invalidate the session, then an attacker has a larger time window to brute force the session ID. From the point of view of session-replay attacks, this is worse since the attacker can replay back a compromised session ID at any point in time, and still get access to a valid user session. You would also want to revisit the duration specified in the session.setMaxInactiveInterval for the value you are using currently is 10 hours. I would consider that to be insecure. Most applications do not require a rolling window of session expiry beyond 30 minutes, with 10 minutes being the value recommended for high-value apps.
Destroy the server-side session and it's contents on expiry. In a servlet container, this is typically done by invoking session.invalidate() in a logout page/link. Ensure that you have provided users with a link to logout from the application in the first place, so that the logout request can be processed to invalidate the session using the before-mentioned API call. If you do not perform this activity, the server-side session object will be destroyed only on session expiry (which will occur after 10 hours of inactivity by the user; now you see why 10 hours is a bad idea).
this is to do with something similar to session hijacking.. where the auth token is held by a hacker to login at a later stage..
in my projects i've added a simple filter which does the following.
every jsp page which is responded would be given an attribute called id (the token is generated using UUID().. the same token is placed in the session..
when a page is posted, the filter (which is configured to filter all requests) checks for the equality of these tokens & proceeds only if the values match.
we also added a timestamp in the session & the database, whenever a page is submitted we check the time stamps in the session with the db.. if the number is within 10 ms then the request passes, else the user is redirected...

Categories