Friday December, 16 2005

Scheme enforcement in Java Webapps using an ssl accelerator    \\ geek

If you've ever used an ssl accelerator with a webapp then maybe you've come accross this problem where your application is effectively incapable of determining which requests are secure versus insecure.

The Problem: When using some form of proxied solution for doing ssl transactions (an ssl accelerator, ssl proxy, etc) the http request that is processed by your application server is unaware of whether or not the original request was processed by your ssl handler. If an application cannot determine which requests are secure versus insecure then it cannot handle scheme enforcement and scheme switching for things like secure logins and registrations. Example ...


request -> https://mysite/index.jsp (ssl handler) -> http://mysite1.server:8080/index.jsp (app server)

This is a very common scenerio, where there is a proxy setup to handle ssl requests before they get to an application server because the proxy can do ssl handshaking much faster than an app server. The problem that arises in this scenerio is that the app server gets the request from the proxy and does not know if the request was originally over ssl or not. More specifically in a Java webapp this means that the value of request.isSecure() will always be "false" because the application server sees the request as a simple http request. This is a problem if your application tries to ensure security for any of its resources.

Possible Solutions: Unfortunately there doesn't seem to be a fix-all solution to this problem, at least not as far as I have seen. The solution is largely dependent on what application server is being used, how the ssl proxy is setup, and how your application is trying to use it's https vs. http protocol switching.

Tomcat offers a fairly easy way to tackle this problem by allowing users to manually specify that all requests on a given connector are secure vs. insecure as well as setting the scheme to https vs. http. Using this approach you simply configure tomcat to have 2 connectors running on different ports, 1 for http insecure connections, the other for https secure connections. For the https secure connector you just need to set the appropriate properties ...


<Connector port="8080" scheme="http" secure="false" />
<Connector port="8043" scheme="https" secure="true" />

Then just setup your proxy to forward insecure requests to tomcat port 8080 and forward ssl handled requests to tomcat port 8043.

If you aren't using tomcat or don't want multiple connectors then an alternative is to try using a custom http header. Often times it's not too difficult to have your proxy set a custom http header for requests that were handled over ssl and if so then all you need to do is enable your application to be aware of that custom header. The easiest way to do that is to define a simple class like MyRequestWrapper which overloads the servlet request.isSecure() method to inspect the request for your custom header. Then use a Filter to wrap the incoming request in your MyRequestWrapper.

I'm sure there are many other alternative ways to tackle this problem, but these two solutions should work for quick a few situations.

Posted by gconf at Dec 16 2005, 12:40:54 PM PST | Permalink | Comments (0)
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

Search

The Grabbag

Powered by
Roller Version 4.0.1.1 (BSC)
© copyright gconf ... don't copy me!