Wednesday, June 11, 2008

https becoming http in case of sendRedirect - why?


https becoming http in case of sendRedirect - why?

Whenever an URL is entered into the address bar of a browser, it normally goes through a sequence of servers in-between before reaching at the actual target server. This intermediate servers may be used for a variety of reasons including load balancing, encrypting/decrypting, SSL Offloading, etc.

SSL Offloading servers actually cause this problem of https URLs getting converted into http URLs in case of sendRedirect. Let's try to understand how it all happens. When an https URL reaches an intermediate SSL Offloading server, the request is decoded (to offload the decoding task which would have been done by the actual target server otherwise) into an http request and the SSL Offloader now sends that decoded http request to the actual target server (it may go through few other intermediary servers for other purposes as well). Now, the target server has no clue whether it was originally an https request or not and it treats it as an http request only. This is the reason why a servlet calling sendRedirect on the target server will result into an http URL for the redirected resource (having a relative URL)and the same http URL is sent back to the client browser. Remember, no SSL Offloading server will come into picture for this URL as it's an http request and not an https request. If the redirected resource is an absolute https URL then also an intermediate SSL Offloader may convert that https request into an http request before it reaches to the client browser.

Example: how it happens typically?

URL typed into the address bar of the client browser
https://hostName:portName/webApp/jsp/jspName.jsp

URL after being intercepted by the intermediary SSL Offloader
http://hostName:portName/webApp/jsp/jspName.jsp (https -> http)

URL received by the actual target server - same as the above
http://hostName:portName/webApp/jsp/jspName.jsp

If redirected resouce is '/jsp/redirectJsp.jsp' - relative URL then URL sent back to the client
http://hostName:portName/webApp/jsp/redirectJsp.jsp

Thus we see that the sendRedirect will cause an https request to get converted into an http request because some SSL Offloader had already converted the incoming https req into an http req in between and the target server (which actually built the URL for sendRedirect) had no clue about this.

What all needs to be done to fix this problem?

Servlet Filtering architecture makes the solution to this problem very easy - at least a very basic solution is not that much difficult. We need to subclass the HttpServletResponseWrapper class, get the URL prefix (to determone if it's an https req or an http req), and override the sendRedirect method. Once, done with this, we can write a sendRedirect filter where the doFilter method would take the 'response' parameter as the object created by passing the original 'request' and 'response' coming to it. Finally, we need to register that filter by having an entry for it in the deployment descriptor. This filter will maintain the default processing for any http request and only the https requests will be treated differently to get the above problem fixed.


Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


3 comments:

Unknown said...

Question about determining whether it is a secure request -- if SSL server always will change the https request to http request, the app server (and hence, the overridden class) will always get http. How does that solve our problem

Geek said...

Hi Viral,

An https request would get changed to an http request only if the request goes through an intermediary SSL Offloader Server (before reaching the actual App Server) and if the URL of the sendRedirect resource is relative. Right? Let's try to understand it this way.

If an https request directly goes to the target App Server then it's guaranteed that this problem won't happen.

What about the case when the request goes through an SSL Offloader, but the sendRedirect resource URL is NOT relative i.e., it's absolute? The problem may or may not happen. If the response (carrying the sendRedirect URL) goes through an intermediary SSL Offloader while its way back to the client browser then it may happen otherwise it won't happen.

I hope it helps you find an answer to your problem. Keep visiting/posting!

kunal said...

Hi,

Thanks for the explaination.I ran in to the exact problem you described.

we have out f5 server configured to redirect all http to requests to https as well as for ssl off loading.so when i am redirecting view to page1.html first it get redirected to http://page.html and then it redirected again to https://page1.html.

so i have following questions

1) is there some rule we can update on load balancer to resolve this issue or it has to be solved through code?

2)can you give more details regarding solution you suggested any code snippets would help a lot.

Thanks ,
Kunal