Load Balancing an https Java Web Application in Tomcat

Discussion in 'Java' started by robert.pappas, Aug 22, 2005.

  1. 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
     
    robert.pappas, Aug 22, 2005
    #1
    1. Advertisements

  2. robert.pappas

    Roedy Green Guest

    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?
     
    Roedy Green, Aug 22, 2005
    #2
    1. Advertisements

  3. 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
     
    robert.pappas, Aug 22, 2005
    #3
  4. The most straightforward solution would appear to be to use relative
    URLs instead of absolute URLs.
    Ray
     
    Raymond DeCampo, Aug 24, 2005
    #4
  5. 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
     
    robert.pappas, Aug 25, 2005
    #5
  6. I see that in section SRV 5.3.
    Such a solution would likely be too slowly realized for your purposes. :)
    Ray
     
    Raymond DeCampo, Aug 26, 2005
    #6
  7. 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
     
    robert.pappas, Sep 16, 2005
    #7
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.