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
Related
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.
It is a web service deployed on Apache Karaf using camel-cxf. I am able to see the cxf service listing in URL localhost:8181/cxf which has some rest and soap services deployed on it.
The problem is it is returning the service listing whenever any request comes with keyword "services". For example the url http://localhost:8181/abcd/services returns cxf service listing page instead of processing the actual request.
I got to know from http://cxf.apache.org/docs/jaxrs-services-description.html that its is because of the default value of service-list-path of CXFServet is services.
Here is my Question. If I want to override this, I should set this property in etc/org.apache.cxf.osgi.cfg. This cfg file is not present under etc folder in my karaf. What are the steps to be taken if I am creating this property file manually? What features I need to install? Or creating this cfg is sufficient ?
Appreciate your help !
There should be no extra installation requirements, just create a new file etc/org.apache.cxf.osgi.cfg.
There are three settings you may be interested in:
org.apache.cxf.servlet.context = /mycxf
org.apache.cxf.servlet.service-list-path = /myservices
org.apache.cxf.servlet.hide-service-list-page = false
Where the default URL for the CXF service listing is usually like http://localhost:8181/cxf/services, with the changes above the URL would become http://localhost:8181/mycxf/myservices
If you change from false (default value) to true, then your services will be hidden and you will instead get a page stating No service was found.
Because these are initialisation settings you need to shut down Karaf for the changes to apply.
I see several points here --
The CXF framework is installed by default in karaf under the context-path /cxf.
/cxf/services can be considered as a CXF internal app that displays the list of services deployed in CXF. I don't think you can configure the name "services" here (and why would you change that?)
the "url-pattern in web.xml" you speak of (if I understand correctly) determines the context path of your servlet/application. You can specify this is camel like this:
<cxf:rsServer id="secureRsServer" address="https://0.0.0.0:8182/my/path/"
serviceClass="....">
(for the RS Server, probably same for the WS server).
I have a web application where I want to track which language a user wants to use to view the various pages. I am using a session attribute to store their selection. I set the session attribute like so...
String languageChosen = request.getParameter("LANG");
request.getSession().setAttribute("LANG", languageChosen);
Then in other methods I retrieve the attribute like so...
String languageChosen= (String) request.getSession().getAttribute("LANG");
When I test this application in my local environment - which is running Tomcat - it works perfectly. But when I deploy the application to our remote development server - which is Weblogic - the session attribute is not being captured. As a result the application is not displaying in the right language.
Should I be storing the session attribute differently for Weblogic? I've never run into this issue before. We have other apps running on the same Weblogic instance that utilize session attributes without issue. Any ideas?
I figured out the problem. The current development URL is not a secure URL and I had the secure cookie setting set to TRUE in my weblogic.xml file. Once I changed it to FALSE everything worked.
Now I just have to remember to change it back to TRUE when we move to a secure environment. Ha ha!!
I'm trying to have my JSESSIONID at ".mysite.com" so it can be shared across subdomains.
I have a 4.2.2 GA JBOSS instance doing this with this method: http://shchekoldin.com/2010/05/27/sharing-jsessionid-across-subdomains/ (which is from here: https://jira.jboss.org/browse/JBWEB-107) using the custom valve approach.
However on the EAP 5.1 version (I've compiled against JDK 1.6) the same custom valve doesn't kick in. I added some debugging but it never gets called.
Also, I tried turning on the SSO option in server.xml (as per https://community.jboss.org/wiki/JBossWebSingleSignOn) through the non-clustered method, but this plays no impact on it either.
Does anyone know how I can the JSESSIONID cookie to sit across subdomains on JBOSS 5?
(Side note, if I have "foo.bar.mysite.com" will this ".mysite.com" domain stored against the cookie work for multiple sub domains - this is for testing, in prod we just have the one level).
I also had same requirement. Share session across sites having sub-domain and parent domain within same .war file. e.g www.baseball.sports.com and www.hockey.sports.com.
To share JSESSION b/w these two sites need to add domain tag in jboss-web.xml.
File path : /app/jboss/jboss-eap-6.1/standalone/deployments/mason_production/.ear/.war/WEB-INF.
Add below entries :
.sports.com
I found what I needed:
You add <SessionCookie domain="example.com"/> under in the WEB-INF/context.xml of your application.
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