Load Balancing an https Java Web Application in Tomcat

R

robert.pappas

Greetings!

We have implemented an HTTPS application on Tomcat, and we run multiple
Application Servers for load-balancing.

Without getting into all the details of what and WHY....we have a
hardware SSL decoder in front of our load balancer.

So, the user browser submits an https request, and the SSL decoder
turns it into an http request, and Tomcat processes the http request.

The only problem is, every time Tomcat generates a page redirect, it
sends a fully qualified URL back to the browser, and it prepends "http"
onto the URL. (Tomcat thinks we are running an http side, but we are
actually running an https site).

And when the user browser receives an "http" redirect after sending an
"https" request, it pops up a security warning to the user. (At least
Internet Explorer does.)

Is there any way to tell Tomcat "Hey, I know the requests are coming in
as http, but please generate all outbound redirects as https!!!"

I found that you could set the "scheme" parameter on a Tomcat
Connector, and that kinda works, but it breaks the Tomcat Login Process
(j_security_check), because j_security_check adds a port number (80) to
the URL. And you end up with an https request going to port
80....which causes a nasty error.

How about we give up on Tomcat and try WebSphere or a commercial
Application Server? Do THEY handle this better?

Any help desperately appreciated!!!

Robert Pappas
(e-mail address removed)
 
R

Roedy Green

Is there any way to tell Tomcat "Hey, I know the requests are coming in
as http, but please generate all outbound redirects as https!!!"

Here are three possible approaches if there is not a clean solution.

1. You could create a miniature webserver to go between Tomcat and
your hardware beast that does nothing but such translations.

2. Under what circumstances does Tomcat generate redirects? Perhaps
you can trap these and handle them at a lower level.

3. Tomcat is open source, is it not. Perhaps you can generate a
version of it that does what you require.


I am curious about your hardware SSL box. Who makes it?
 
R

robert.pappas

Thanks Roedy,

1. This is not a bad idea! It's another piece we'd have to add, and
it's not a clean solution, but it could work. And maybe one of our
smart routers could do the same. Our routers do have an internal
scripting language....hmmm.

2. Any and all redirects. If you do
response.sendRedirect("someaddress") anywhere in Java, it will always
generate a fully qualified URL in the "Location:" field of the returned
302 Header. There are things you can do like "Servlet Filters" which
can alter outbound traffic. However, the Tomcat Login Process
(j_security_check) is immune to Servlet Filters (for security reasons)
and it uses a page redirect to redirect the user into the site after
successful login. The LAST place we want our users to get a security
warning is on the login page. :)

3. That is what I have done as a temporary work around. I changed the
org.apache.catalina.connector.Reponse object to allow relative URLs in
a redirect. And I recompiled catalina.jar, and this works fine.
However, I don't like this solution because it violates the Java
Servlet spec which states that all redirect URLs must be fully
qualified. It also makes for a maintenance issue having to maintain
our own custom Tomcat.

The SSL box is made by Radware. We have to decrypt the incoming
traffic before it reaches our load balancer, because the load balancer
can't read an encrypted request. And it needs to be able to read the
incoming request, because it has to be able to see the user's cookies
in order to tell which server to send the request to. We are using
"Server Affinity" to pin a user to a given server for the life of their
HttpSession. That way we don't have to replicate their HttpSession
data across all the servers. (ugly) And so, we decrypt the stream up
front. This solution is described here:

http://www.onjava.com/pub/a/onjava/2001/09/26/load.html?page=2

Thanks for your tips! I'm probably going to try and look for software
or hardware solutions that implement #1. :)

Robert Pappas
 
R

Raymond DeCampo

Greetings!

We have implemented an HTTPS application on Tomcat, and we run multiple
Application Servers for load-balancing.

Without getting into all the details of what and WHY....we have a
hardware SSL decoder in front of our load balancer.

So, the user browser submits an https request, and the SSL decoder
turns it into an http request, and Tomcat processes the http request.

The only problem is, every time Tomcat generates a page redirect, it
sends a fully qualified URL back to the browser, and it prepends "http"
onto the URL. (Tomcat thinks we are running an http side, but we are
actually running an https site).

The most straightforward solution would appear to be to use relative
URLs instead of absolute URLs.
And when the user browser receives an "http" redirect after sending an
"https" request, it pops up a security warning to the user. (At least
Internet Explorer does.)

Is there any way to tell Tomcat "Hey, I know the requests are coming in
as http, but please generate all outbound redirects as https!!!"

I found that you could set the "scheme" parameter on a Tomcat
Connector, and that kinda works, but it breaks the Tomcat Login Process
(j_security_check), because j_security_check adds a port number (80) to
the URL. And you end up with an https request going to port
80....which causes a nasty error.

Ray
 
R

robert.pappas

Yes, I wish we could, but Tomcat's native behavior is to generate
absolute URL's on all redirects. And that cannot be changed. (And
besides, it would be a violation of the Java Servlet spec to send
relative URLs).

What we REALLY need is for the Java community to change the spec to
allow relative URLs from the "sendRedirect" method. But I suppose
there's some good reason why they require it. (?)

=)

Bert
 
R

Raymond DeCampo

Yes, I wish we could, but Tomcat's native behavior is to generate
absolute URL's on all redirects. And that cannot be changed. (And
besides, it would be a violation of the Java Servlet spec to send
relative URLs).

I see that in section SRV 5.3.
What we REALLY need is for the Java community to change the spec to
allow relative URLs from the "sendRedirect" method. But I suppose
there's some good reason why they require it. (?)

Such a solution would likely be too slowly realized for your purposes. :)

Ray
 
R

robert.pappas

Yay! I came up with a solution to my own problem. Here is what you
do:

In Tomcat server.xml, you can configure the Connector to run behind a
proxy using the proxyName and proxyPort parameters.

Here is the relevant piece of Tomcat documentation on these parameters:

"The proxyName and proxyPort attributes can be used when Tomcat is run
behind a proxy server. These attributes modify the values returned to
web applications that call the request.getServerName() and
request.getServerPort() methods, which are often used to construct
absolute URLs for redirects. Without configuring these attributes, the
values returned would reflect the server name and port on which the
connection from the proxy server was received, rather than the server
name and port to whom the client directed the original request."

Well, in my case, I'm running Tomcat behind an SSL decoder, not a
Proxy, but the effect is the same, and the solution is the same.

So, in the Connector attributes, I set the "proxyName" to the server
name of my website as seen from the outside world. I set "proxyPort"
to 443. I set "scheme" to "https", and I set "secure" to "true".

And it works!!! When Tomcat generates absolute URL's, it knows to use
these parameters to build the URL rather than the values from the
incoming request.

This solution seems so obvious in hindsight, but coming from the other
direction, I didn't know what to look for. I was doing tons of reading
on the topic of "SSL with Tomcat" and not on the topic of "proxies with
Tomcat".

Hope this helps someone else!

Robert Pappas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top