I am trying to implement a sticky session based load balancing across two Tomcat instances using the Hazelcast Tomcat Web Session Replication. For testing purposes, I have deployed the application on two different Tomcat instances and the load balancing is handled through Apache HTTPD. The jvmroute parameters and the mod-proxy settings are fine and the load balancing has no issues.
The problem is with the session replication across the two instances. When the first server (currently serving the request) goes down the request is sent to the second server. The Hazelcast cluster identifies that the session is through fail-over and is copying the session with the new session id (suffixed with the jvmroute parameter of the second server) - as described in the Hazelcast documentation https://github.com/hazelcast/hazelcast-tomcat-sessionmanager#sticky-sessions-and-tomcat) . However for the failed-over request, the session attributes are getting updated in the older session(failed over jvmroute) and not getting replicated resulting in the failure of the subsequent request.
I have gone through the documentation but unable to find a resolution at this point. I am sure I am missing some setting as this would be a basic setting for a fail over scenario.
Can someone help me out? Please let me know if you need any additional details.
[UPDATE]
After tracing the flow, able to determine that the handleTomcatSessionChange in com.hazelcast.session.HazelcastSessionChangeValve is being called correctly. The request.changeSessionId(newSessionId) call happens and post this if I display the value of the requestedsession id, the value is updated. However, the session id by itself is not updated and this is resulting in the older id in a request.getSession().getId() call.
Related
There are two server applications deployed in Tomcat.
OAuth2 Authentication Server
OAuth2 Resource Server
The OAuth2 Server authenticates and authorizes the usage of Resource server. This setup is working fine and there are no issues regarding this.
Now I m in need to implement session tracking mechnism in the resource server, so that i can store and retreive session attributes between different api calls in the resource server.
To acheive the above I have configured and implemented session storage as such with the below code
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
and the above configuration created the required tables in the db and the session_attributes are storing just fine.
The problem is between every api call new session is created indefinite of weather I use different configurations like below
request.getSession()
request.getSession(true)
request.getSession(false)
request.getSession(false) => only using this line makes the code to fail as it prevents from creating a new session even if there are no sessions.
Anyhow, after reading numerous technical documents it seems like we need to implement the said mechnism with either HeaderHttpSessionStrategy or CookieHttpSessionStrategy, but there are no clear documentation available and the dependency is not getting resolved for spring-session which contains the required classes.
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>x.x.x/version>
</dependency>
I tried this, but in vain
Help me with a solution. Thanks in Advance
I have deployed my spring boot application on GAE, Java 11, Standard Environment. As per the documentation for Java11 we need to use app.yaml for configuring the instances.
I wanted to know as to how I can enable sharing of sessions between instances. As per my research, Earlier we could simply solve this problem by setting sessions-enabled and async-session-persistence in appengine-web.xml. With appengine-web.xml gone, what is the equivalent way of doing this in app.yaml.
Use case that i am trying to achieve is :
Using spring security (Unfortunately i get logged out when according to me the request of the same user goes to another instance.)
Storing the user retrieved from DB in a #SessionScoped variable so as to avoid multiple DB calls.
Any help here would be really appreciated. Thanks!
I went through a lot of documentation, but I believe that this is not inside the app.yaml configuration reference.
Alternatively, I could find that you could use session affinity in order to use a instance to reply always the requests of a same user, this can be enabled in your app you can use the next tag in your app.yaml according to this documentation.
network:
session_affinity: true
Hope this works for you.
Recently, we have upgraded our application server from JBoss EAP6.2 to EAP7.0.
Even though it runs non-HA profile aka standalone.xml, JBoss adds jboss.node.name at the end of JSESSIONID cookie.
For example,
Spring Boot generates a JSESSIONID as tHSf9v23SSDBMqJ1O7XFJZ9.... and when the request comes to browser, the cookie becomes tHSf9v23SSDBMqJ1O7XFJZ9.master:<jboss.node.name> which causes some compatibility issues.
I've run some experiments by manually calling response.addCookie. In that case, it does not add master suffix to the cookie. However, if Spring itself writes the cookie, it seems that JBoss picks it up and add master suffix. I know this case can be little confusing (it is to me), I'm happy to provide more information.
An old thread, but for those who still stumble upon it:
In EAP7/Wildfly11+ the session cookie will have a value in form :
<sessionId>.<instanceId>
Where instanceId is taken from Undertow subsystem config attribute instance-id. By default it is going to be set to value of jboss.node.name system property in standalone mode, and to <serverGroup>:<hostname> in domain mode.
You can customize the instanceId value via Undertow subsystem config:
Either via standalone.xml:
<subsystem xmlns="urn:jboss:domain:undertow:3.1" instance-id="${myValue}">
Or via corresponding cli:
/subsystem=undertow:write-attribute(name=instance-id, value=myvalue)
In which case you get a final JSession id that looks sth like this:
JSESSIONID=FdEyt_nZvyAV1gKpQ_3ZsSYeu41JycphvMdHcYeT.myvalue
The answer from #yntelectual is dead right and should be the accepted answer.
I just want to complement the fact that the observed behaviour is not a JBoss speciality.
It was introduced so Apache mod_jk and mod_proxy know which one of several possible application servers is working on a given session, and Apache Tomcat as the reference implementation for servlet containers shows exactly the same behaviour. Other containers such as JBoss, Glassfish, Geronimo do the same.
Check
jvmRoute on https://tomcat.apache.org/tomcat-9.0-doc/config/engine.html
jvmRoute on https://tomcat.apache.org/connectors-doc/reference/workers.html
route on https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
jvmRoute on https://docs.oracle.com/cd/E18930_01/html/821-2416/gfaad.html
jvmRoute on https://geronimo.apache.org/GMOxDOC11/geronimo-tomcat-host-level-clustering-sample-application.html
There is a Java webapplication deployed in tomcat and Apache webserver.
There is only one tomcat instance in production and there is no concept of loadbalancer.
But, after introducing Apache webserver, User A is able to completely see User B s data, meaning, User B's session is accessed by User A.
The same code was working fine, when there was only tomcat instance, now on introducing Apache web server, we are facing this session data crossover issue.
//httpd.conf properties
worker.list=tomcat_lb,jkstatus
# Define a 'jkstatus' worker using status
worker.jkstatus.type=status
worker.tomcat_lb.type=lb
worker.tomcat_lb.balance_workers=tomcat_1
#worker.tomcat_lb.balance_workers=tomcat_1,tomcat_2
# Specifies whether requests with SESSION ID's
# should be routed back to the same #Tomcat worker.
worker.tomcat_lb.sticky_session=True
I need to prevent Session Fixation, a particular type of session hijacking, in a Java web application running in JBoss. However, it appears that the standard idiom doesn't work in JBoss. Can this be worked around?
This defect (found here) points the way to the solution. The Tomcat instance that runs in JBoss is configured with emptySessionPath="true", rather than "false", which is the default. This can be modified in .../deploy/jboss-web.deployer/server.xml; both the HTTP and AJP connectors have this option.
The feature itself is used to eliminate the context path (eg. "foo" in http://example.com/foo) from being included in the JSESSIONID cookie. Setting it to false will break applications that rely on cross-application authentication, which includes stuff built using some portal frameworks. It didn't negatively affect the application in question, however.
This problem and the specific case in which it occurs is a problem in Tomcat as well as JBoss. Tomcat shares the emptySessionPath="true" effect (and actually JBoss inherits it from Tomcat).
This really seems like a bug in Tomcat and JBoss when you are trying to prevent session fixation attacks but the servlet spec (at least version 2.3) does not actually require the JSESSIONID to be defined or redefined according to any specific logic. Perhaps this has been cleaned up in later versions.
One workaround is to store the client address in the session. A response wrapper should validate the client address set in the session is same as the one accessing the session.
I came to know below code setting snippet from one of the forum. And I added below lines. But when I print the session ID after and before log in into the application it is same. How would I test session Fixation.
D:\jboss-5.1.0.GA\bin\run.cof file and add the below line.
set "JAVA_OPTS=%JAVA_OPTS% -Dorg.apache.catalina.connector.Request.SESSION_ID_CHECK=false"
in each context.xml of the jboss applications.
D:\jboss-5.1.0.GA\server\default\deploy\jbossweb.sar\context.xml