Tomcat secure sessions with ajp and http protocols using apache proxy balancer
May 20th 2011
During this week I have been digging into Apache AJP protocol and how it communicates with Tomcat. Especially, I have been interested in knowing how SSL works in different Tomcat connector setups. Once again in hindsight everything is so clear but had many desperate moments during these days :)
Anyways, you should first check ajp protocol. Basically, I have tried two different solutions:
- Apache proxy balancer using HTTP
<Proxy balancer://liferaycluster> BalancerMember http://node1 route=node1<br> BalancerMember http://node2 route=node2<br> ProxySet stickysession=ROUTEID<br> </Proxy>
- Apache proxy balancer using AJP
<Proxy balancer://liferaycluster> BalancerMember ajp://node1 route=node1 ping=3<br> BalancerMember ajp://node2 route=node2 ping=3<br> ProxySet stickysession=ROUTEID<br> </Proxy>
Benefit of using AJP is the "ping" setting which Apache uses to check whether Tomcat is up or down and does more sophisticated load balancing based on that information. However, things become more tricky in Tomcat connector configurations when checking whether JSESSION will end up to be "secure" or "not". In HTTP connector you can define secureness of your connector like so:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="false" scheme="https" secure="true" proxyPort="443"/>
But if you define connector with AJP protocol:
<Connector port="8443" protocol="AJP/1.3" SSLEnabled="false" scheme="http" secure="false" proxyPort="443"/>
"Secure" setting will not have any effect to JSESSIONID cookie. However, it does have an effect to function call "ServletRequest.isSecure()". Go figure.
It seems that AJP protocol contains boolean value wheter initial connection to Apache was secure or not and that value is passed to Tomcat which uses that information to create user session cookie.
If you need an AJP setup where JSESSIONID should not be secure even if initial connection was through HTTPS you can do Apache haxing to remove Secure setting from cookie like so:
Header edit "Set-Cookie: JSESSIONID=" Secure " "
This will replace word Secure with empty string from JSESSIONID cookie. <strong>This is not the most clever thing to do because now your session is open for hijacking.