Saturday, March 20, 2010

Offloading SSL encryption

It is very common to use SSL encryption (https - protocol scheme) to secure web application, to transfer the form data in encrypted format. It is also common to have SSL encryption getting off loaded after CSS (Content Services Switch) in non-financial applications because maintaining 'https' in end-end flow requires a complex configuration around an Application Server / Web Server.

SSL Off loading means CSS drops the 's' from https, passes client's request to web server as plain http request and takes care of dropped encryption while processing the response to client.

So 'SSL offloading' is seem less to client & further web requests shows up with 'https' only....... then what is the problem here ? if everything works fine...   of course the problem arises when an application logic tries to  redirect the request by forming an explicit URL unless it addresses the protocol scheme accordingly...

In general what happens when we form a URL for re direct, we read the request parameters as below..

public void redirectURL( HttpServletRequest request,  HttpServletResponse response) {

String scheme = request.getScheme();
String serverName = request.getServerName();
String portNumber = request.getServerPort();

String url = schme + "://" + serverName + portNumber + request.getServletPath();
response.sendRedirect(response.encodeRedirectURL(url));
}


The problem comes at the line String scheme = request.getScheme();
it returns only 'http' because 's' was offloading before even the request came to web server, now we are redirecting with pain 'http' protocol to a secured application. Hence the security component will reject the request shown un authorized page.

To address this issue we need to be careful while redirecting a servlet reqeust to accomdate with 's' in protocol scheme if it is a secured application. Modify the above line as below, leave the port number as it can vary for 'https' versus 'http'.
String url = "https"+ "://" + serverName +  request.getServletPath();

So final application logic looks like...

public void redirectURL( HttpServletRequest request,  HttpServletResponse response) {

String scheme = "https";
String serverName = request.getServerName();
String portNumber = request.getServerPort();

String url = schme + "://" + serverName + request.getServletPath();
response.sendRedirect(response.encodeRedirectURL(url));
}