Implementing Oracle SSO in a generic java container? It is not as easy as you think.

Recently Rich and I got a chance to implement the mod_osso for any generic java container. The current mod_osso module only works in Oracle iAS, but we would like to use Oracle single sign-on in virtually everywhere. We can then use it for development, testing, or even production when we don’t need a relatively heavy Oracle iAS solution every time. Our implementation uses a filter to intercept the request and response, and interacts with the SSO server in specific conditions.

We know the basics about communicating with a single sign-on server. Simply put, authenticate if your apps ask you to, keep users logged in if the their sessions are not timed out, and log them out if the users want to. Simple, eh?

After we started testing the code we have written, funny issues just keep coming up when we debug it. Ok, the page does show up. Why? No idea. Ok, now java throws up with illegal state exceptions? Ok, the redirection request to SSO server takes forever and never completes? As we dig into it a bit more, issues will come up, and we need careful analysis to figure out what is really wrong.

For the HttpServletRequest, it only allows read, not write. For the HttpServletResponse, it only allows write, not read. However, in order to set user credentials and pass the information to your app, and to be able to intercept the response and redirect to Single sign-on server, you need write access to the request object and read access to the response object. One way is to use wrappers around these objects and overwrite the functions. The key thing is you need to make sure you implemented all the functions that you need to overwrite and implement these functions appropriately. The problem is that you would never know what you don’t know, as you only know what you know.

Caveats:

1. You can not allow your app to actually output anything to the outputstream, as the response would considered to be committed and you would not be able to modify it when you receive it at your filter. An illegalstateexception would be thrown. There are all sorts of ways an app can possibly output to the outputstream, and you basically needs to be able to capture them all.

2. After you can avoid users from outputting to the response, your redirection request to the sso server may hang or takes a long time to respond. One potential reason which took some time to figure out is that somewhere some place has called response.getOutputStream() or response.getWriter(). If these functions are called, java would think that there is a possibility the app would be writing to the stream, so it will not close the response, waiting for the data which would never arrive, and your browser would just hangs there forever. In addition, you also need to set the content length to 0 to ensure java knows that it is safe to send out the response.

The caveat list can be very long, and the above is just to give you a taste of it. These things are not mentioned in javadocs, and you can only realize them as you run into them. Even you know quite a lot about security, networking, java, filter, apps, java containers, and all the concepts required to implement SSO, it is just not enough. A lot have to do with trial-and-error and your patience in executing it through. I guess that is why employers ask whether you have experience on this, and experience on that?

4 comments

  1. Thankfully mod_osso and OSSO is history (long live OAM and the rest of IDM suite). The architecture of OSSO et al is extremely, well, unfortunate.

  2. Does Oracle provide a connector to an authN/authZ framework such as Acegi/Spring Security?

    That's how we (Atlassian) tackled the problem of customers needing to write their own filter every time… massively reduces the complexity required to get a new app up and running.

    Life's too short to rewrite all this stuff 😉

  3. Yep, life is short and time is limited. If we got enough interests, we will try and share our code.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.