1

I have a Java servlet that sits behind a hardware load balancer. The load balancer only allows https requests. The problem is when I get the request in the servlet, I can only see http, it seems it has been decrypted by the time it gets to the servlet, which makes sense because the servlet should not worry about security. When I want to send a redirect in servlet, however, the request will be blocked by the load balancer because it will be a http request.

I read about some solutions and they're all similar to this one. Basically people suggest to add a servlet filter to catch the request url first.

I tried but it didn't work. What I don't quite understand is that as long as the servlet has no way to know about the actual request (http/https), how can servlet filter do any help? I also wonder if there's any standard solution to this issue since I think it's quite common.

Piyush Mattoo
  • 15,454
  • 6
  • 47
  • 56
J Freebird
  • 3,664
  • 7
  • 46
  • 81
  • @J Freebird : Hey can u pls tell me how did u solve your issue. I am facing a similar situation. my post is at : https://stackoverflow.com/questions/62434681/how-to-fix-https-http-mixed-content-error-in-jsp-redirection-in-a-java-web-appli – Som Jun 17 '20 at 17:57

3 Answers3

1

You can actually know if the request to load balancer was http or https. The load balancer will send you certain headers that tells you about the original request.

For Ex, It will send X-SSL-Secure : true header if the request to load balancer was HTTPS.

Please refer here .

How can I know if the request to the servlet was executed using HTTP or HTTPS?

Community
  • 1
  • 1
Ramesh PVK
  • 15,200
  • 2
  • 46
  • 50
  • Unfortunately, the load-balancer didn't pass me the `X-SSL-Secure` header. – J Freebird Aug 26 '16 at 21:15
  • @can you paste here all headers you can receiving. May be they are sending some other headers. – Ramesh PVK Aug 26 '16 at 21:25
  • I checked all the headers, all of which seem to be just standard ones, having nothing to do with security. Is it a protocol for load-balancers to set certain header when it's https? – J Freebird Aug 27 '16 at 18:27
  • Yes. Which load balancer do you have? May be it needs some configuration. – Ramesh PVK Aug 28 '16 at 01:32
  • Not sure. For what I know, it's a hardware load-balancer and I'm not supposed to change that. Maybe need to do something like forwarding rather than redirecting in this case. – J Freebird Aug 28 '16 at 18:54
  • @JFreebird : Hey can u pls tell me how did u solve your issue. I am facing a similar situation. my post is at : https://stackoverflow.com/questions/62434681/how-to-fix-https-http-mixed-content-error-in-jsp-redirection-in-a-java-web-appli – Som Jun 17 '20 at 17:59
0

HTTPS is just HTTP protocol over SSL. It only encrypts the data packets transferred between your client & server using certificates.

Your Servlet should not bother what underlying mechanism is used. The transport protocol is a contract between your client & container. Your servlet remains transparent of how the communication takes place at network level.

The redirect warnings you are getting may be because of security enforcements. Generally most modern browsers allow you to go from HTTP to HTTPS but not other way round.

For example - if your home page is loaded in HTTPS but your browser will block asynchronous calls(any ajax calls) that you are making over HTTP. This is done to enforce you to use HTTPS on all the pages on your site.

There could be 2 scenarios here that you might want to check:

1) Are you getting this warning at client browser. As I already explained above, this might be the cause of your issue.

2) Like browser, your load balancer might be doing any such security enforcement.

Tip: Generally whenever we use redirection in our servlet or any backend code. Dont specify the protocol explicitly wherever you are using URL's. It could be in your redirection code or any other places. Even in the anchor tags you are generating

Dont write :

<a href="http://mywebsite.com/page1"> page1 </a>

Instead, let your client browser handle the protocols(additionally if the URL lies in same domain, Also use domain relative URLs. Use Absolute URLs only if they are external to your site).

<a href="mywebsite.com/page1"> page1 </a>

This way if your same servlet/backend code will work irrespective whether you are using HTTPS or not.

One more thing: The HTTPS or HTTP over SSL is between your client & web-server layer. Your container/App server doesn't(or shouldn't) even know what is going on between them. It is also recommended to use SSL between your webserver & Appserver and have end-to-end encryption.

Rajesh Pantula
  • 10,061
  • 9
  • 43
  • 52
  • That's exactly what I understood and what I did. I just `response.sendRedirect("/context/path/")`. It will redirect to `http://hostname/context/path/`. The issue is the hardware load-balancer won't allow any http requests. So after the browser makes such a request, it will just hang there and finally timeout. The load-balancer is not something that I can touch and modify. – J Freebird Aug 26 '16 at 01:19
  • Hi @JFreebird, where is this redirect happening? does you browser already get url with http:// appended? If yes, then there is somewhere a URL rewriting happening. Generally a lot of systems(especially content management systems), doesn't want broken URLs to be published and they have something called as a URL rewriting mechanism which rewrites the URL's with appending domain name and protocol(therefore converting relative URLs to absolute URL's). Check if you have anything at your webservice layer or load balancing layer which does this. – Rajesh Pantula Aug 26 '16 at 08:36
  • I send the redirect in my servlet, and the browser gets the response and then visit the redirect url. My browser gets https://hostname/path redirect url rather than https. I think that's because the servlet only knows about http when it's sending the redirecting. The url sent from servlet is complete in itself, but it's http. So I don't think there's a broken url. – J Freebird Aug 26 '16 at 17:09
0

We need to redirect the request on conditions properly before executing the below line.

response.sendRedirect("some.jsp");

Hold the schema/referrer like below :

String scheme      = request.getScheme();
String referer     = request.getHeader("referer");

It is better to use referrer because schema doesn't always give the desired result. You can check the value in console debugger.

Then execute the redirect on condition like this :

String servername  = request.getServerName();
String scheme      = request.getScheme();
String referer     = request.getHeader("referer");

if(referer.startsWith("https")) {
    response.sendRedirect("https://" + servername + "/context-root/" + "some.jsp");
}else{
    response.sendRedirect("some.jsp");
} 
Som
  • 1,522
  • 1
  • 15
  • 48