Skip to content

Instantly share code, notes, and snippets.

@esfand
Last active December 30, 2015 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esfand/7787704 to your computer and use it in GitHub Desktop.
Save esfand/7787704 to your computer and use it in GitHub Desktop.
Glassfish redirect https to http behind load balancer

Glassfish 2.1.1 redirect https => http behind load balancer

We are trying to get our webapp to run on 3 Glassfish servers that are behind a load balancer. The load balancer is handling the SSL traffic and off loading the request to port 80 on the Glassfish servers. However, when Glassfish executes a redirect (even if the redirect is a relative URL) it is re-writing the URL and replacing the HTTPS with HTTP. Is there any way to stop this from happening?

here is a mock example of what is happening:

  1. request to https://www.glassfishserver.com
  2. redirect is issued to https://www.glassfishserver.com/webapp
  3. Glassfish then re-writes it and send the redirect to the client as http://www.glassfishserver.com/webapp

Any help would be appreciated.

Answer 1

Hi,

You do not need to redirect to https location in GlassFish. Just redirect to http://www.glassfishserver.com/webapp in GlassFish. The load-balancer plugin will take care of converting http to https. This is based on rewrite-location being set to true(default setting) in load-balancer xml. Refer to document : http://docs.sun.com/app/docs/doc/821-0182/gbwwx?l=en&a=view

Kshitiz

Question 2

We aren't using the Glassfish Load Balancing plugin. We have an external load balancer that is handing off the traffic to Glassfish.

Answer 2

In such a case, you need a mechanism to indicate to GlassFish that original request was over SSL. Your external load-balancer must add some headers to proxied request to indicate that. Then you need to provide implementation of ProxyHandler and set it in GlassFish which handles parsing of headers added by external load-balancer and set values appropriately on HTTP request. Take a look at default implementation of ProxyHandler, i.e. com.sun.enterprise.web.ProxyHandlerImpl, in GlassFish.

Kshitiz

Using HTTPS with GlassFish

Can anyone tell me how I can use HTTPS with GlassFish ?

It seems like just using HTTPS instead of HTTP works for apps that don't require HTTPS, but for my apps that do require it (by setting CONFIDENTIAL in web.xml), I get a 403 Forbidden when I try to access a page.

For example:

https://glassfish-svanimpe.rhcloud.com/authdemo/ -> This app requires HTTPS for all pages and does not work on OpenShift. Locally I would access it via https://localhost:8181/authdemo/

https://glassfish-svanimpe.rhcloud.com/reminders/api/users -> This webservice does not require HTTPS, yet it does seem to work with either HTTP or HTTPS.

Answer

The solutions for Apache and JBoss, not GlassFish:
https://www.openshift.com/kb/kb-e1044-how-to-redirect-traffic-to-https

For Glassfish with a little help on IRC, I finally got this working !

What I had to do was:

  • Stop using CONFIDENTIAL in web.xml.
  • Use a servlet filter instead to forward HTTP requests to HTTPS. My code for this filter is as follows. Also don't forget to set up this filter in web.xml.
@WebFilter(filterName = "HttpsFilter", urlPatterns = {"/*"})
public class HttpsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest request, 
                         ServletResponse response, 
                         FilterChain chain) 
                         throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest)request;
        if (!httpRequest.isSecure() &&
            !httpRequest.getHeader("X-Forwarded-Proto").equals("https")) {

            StringBuilder newUrl = new StringBuilder("https://");
            newUrl.append(httpRequest.getServerName());
            if (httpRequest.getRequestURI() != null) {
                newUrl.append(httpRequest.getRequestURI());
            }
            if (httpRequest.getQueryString() != null) {
                newUrl.append("?").append(httpRequest.getQueryString());
            }
            HttpServletResponse httpResponse = (HttpServletResponse)response;
            httpResponse.sendRedirect(newUrl.toString());
        } else {
            if (chain != null) {
                chain.doFilter(request, response);
            }
        }
    }

    @Override
    public void destroy() { }
}

in web.xml:

<filter>
    <filter-name>HttpsFilter</filter-name>
    <filter-class>HttpsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HttpsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Note the use of the x-forwarded-proto header. If I only used request.isSecure(), I had redirect issues. With this setup, the application behaves as desired, independent of any other applications.

Glassfish HTTPS redirect behind SSL offloader and Apache

I have this configuration:

  1. HTTPS load balancer / SSL offloader on port 443
  2. Apache httpd on port 80 (different IP), using ProxyPass, ProxyPassReverse to forward to... multiple Glassfish domains listening on different ports

Problem: Neither Glassfish nor Apache is aware that the request is HTTPS. Redirects to URLs like "/index.jsp" are being rewritten in Glassfish as http://internal_ip/index.jsp, then ProxyPassReverse rewrites to http://public_ip/index.jsp. Problem is, I need that URL to be https://public_ip/...

How do I fix that - is there some Glassfish configuration I can change, or Apache httpd.conf?

Answer 1

I see two solutions to that:

  1. use your loadbalancer to manipulate apaches response (iRule in F5, flex for A10 loadbalancers etc.)

  2. set up something on the loadbalancer to send another redirect to requests coming in via HTTP to use HTTPS

Response 1

I already have the redirect in place, so all content is served over HTTPS. The problem I'm trying to solve is the IE popup warnings "you are about to access an insecure site" that briefly flash when the browser attempts to follow HTTP redirects (and is then redirected to HTTPS) –

Response 2

I agree, having loadbalancer re-write Location header in response (analogous to Apache ProxyPassReverse, if Apache were doing load balance and SSL offloading) is probably the best solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment