Archive for June, 2010

Apex and SSO blank white screen problem: SOLVED

June 18, 2010 1 comment

Apex and SSO: The White Screen Problem

Unicorn MeatYou may have configured Apex to use Oracle Single Sign On (SSO) as your authentication scheme using instructions such as those found here. If you have, you may have noticed that if you leave the login screen (i.e. login.jsp) sat idly displayed in your browser for more than a certain amount of time (I’ve not done precise timings but it seems to be something like 5 minutes) and then try to login, when you click the Login button you’re presented with a blank white screen and nothing more.

Below, I offer a solution to this problem.

Why it happens

Before we talk about how to fix this, let me describe what I think the problem is here…

When you first request access to your Apex application which has SSO set as its authentication scheme, Apex generates a brand new shiny Apex session id for you and then redirects you to the SSO login screen (login.jsp be default but you may have modified this to be your own custom jsp) for you to enter your credentials. This jsp contains a hidden item with a name of site2pstoretoken (a name mandated by SSO). The value of this hidden item is a long string of seemingly random characters (V1.2~75D127345~6a5DDF88CFDCE765FBEF…). This string is in fact an encoded representation of various bits of data. The important bit of data for us which is encoded in this long string is the URL that SSO should forward us to when we have clicked the Login button and been successfully authenticated by SSO. The actual URL that is encoded in this string which SSO will try to forward us to is:


Where server and pls/apex and 100 and 10 are replaced by the relevant server name, DAD, application number and page number respectively. The crucial bit is the session id at the end (12345678 in the example). This will be replaced by the brand new shiny Apex session ID that Apex assigned to us. How did this URL get encoded into site2pstoretoken? It was passed when Apex originally redirected us to SSO.

So site2pstoretoken contains a URL to forward to. So what?

Good question. It seems that the brand new shiny Apex session ID which was originally assigned to us has the ability to “time out”. Once it has “timed out”, if you click Login on the login.jsp page, SSO will try to redirect you to f?p=100:10:12345678 (*). Since the session has “timed out”, Apex shows you just a blank white screen.

(*) Note: To be precise, the login.jsp submits to /sso/auth which in turn redirects you to /pls/apex/wwv_flow_custom_auth_sso.process_success. In the redirection to wwv_flow_custom_auth_sso.process_success, the site2pstoretoken is included in the url in the “urlc” parameter (e.g. /pls/apex/wwv_flow_custom_auth_sso.process_success?urlc=V1.2~75D127345~6a5DDF88CFDCE765FBEF…). It is this process_success procedure which appears to display the blank white screen. For info: the wwv_flow_custom_auth_sso is created when you ran custom_auth_sso.sql (see step 5 in the instructions for setting up Apex with SSO). I am not sure exactly what the process_success procedure is checking to cause it to display a white screen (the code is wrapped so can’t be inspected). The only thing I can hazard a guess at is that it looks in the <Apex schema>.wwv_flow_session$ table and if the ON_NEW_INSTANCE_FIRED_FOR column has not been populated within a certain amount of time since the session was created (CREATED_ON column) then it shows a white screen. (The ON_NEW_INSTANCE_FIRED column I’ve noticed is only populated once you actually access a page of your application. Just being redirected to SSO does not populate it.)

Anyway, how do we fix it?

So even though we can’t tell exactly the reason why wwv_flow_custom_auth_sso.process_success displays a white screen if you attempt to login after the login screen has been idle for some time, we can put in place a workaround to stop this happening. If we were to somehow refresh the site2pstoretoken on the login JSP periodically so that the value it held always represented (in an encoded form) a URL to redirect to which contained a valid, non timed-out Apex session then the problem should disappear. This can be achieved with a bit of Ajax in the login.jsp as follows. The javascript is all contained in +”…” syntax because it’s all part of one long out.println() call in your JSP. Also notice that I’ve wrapped 3 of the longer lines (the ones that don’t begin with a + below) just to fit into the format of this blog. You’d need to remove these 3 extra line breaks in your jsp :

+"function getXmlHttpRequestObject() {\n"
+"if (window.XMLHttpRequest) {return new XMLHttpRequest();} \n" 
+"else if(window.ActiveXObject) {return new ActiveXObject('Microsoft.XMLHTTP');} \n" 
+"else { alert('Your browser does not seem to support XMLHTTP.');} \n"

+"function getToken() { \n"
+"if (receiveReq.readyState == 4 || receiveReq.readyState == 0) { \n"
+"'GET','http://myserver:7777/gentoken/f?p=234:10',true); \n"
+"receiveReq.onreadystatechange = handleGetToken; \n"

+"function handleGetToken() { \n"
+"if (receiveReq.readyState == 4) { \n"
+"processedResponse = receiveReq.responseText;\n"
+"processedResponse = processedResponse.substring(
   processedResponse.indexOf('VALUE=\"')+7); \n"
+"processedResponse = processedResponse.substring(
   0,processedResponse.indexOf('\"')); \n"
+"document.getElementsByName('site2pstoretoken').item(0).value =
   processedResponse; \n"
+" \n"
+"var receiveReq = getXmlHttpRequestObject(); \n"

You’ll notice above that the Ajax / XMLHTTP request is made to http://myserver:7777/gentoken/f?p=100:10

In this example configuration, the Infrastructure tier (where SSO is installed) is accessed on port 7777. This is the same port on which you will be accessing login.jsp. The apex application is served using MODPLSQL from a different instance of Apache on port 80. So, really, we would need to make a call to server:80/pls/apex/f?p=100:10 but the problem is that browsers do not permit you to make cross-domain Ajax / XMLHTTP requests. Hence, we make the request to the same domain as we are currently on ( and add a proxy entry into the Infrastructure’s httpd.conf file to automatically forward any requests to server:7777/gentoken/ to server:80/pls/apex/. Whether you need to do this kind of configuration of httpd.conf will depend on your setup but for completeness the kind of entry you would need to add to your Infrastructure’s httpd.conf would be as follows:

<IfModule mod_proxy.c>
ProxyRequests On
ProxyPass /gentoken/ http://server:80/pls/apex/
ProxyPassReverse /gentoken/ http://server:80/pls/apex/

What is all that Javascript doing?

It is essentially requesting access to our Apex application again. Again, Apex realises the application is protected by SSO so assigns us a shiny new Apex session ID and forwards us to SSO. Or rather, it can’t actually forward us in this case because all this is is an XMLHTTP request, but it does still return HTML which, if we were a browser and not an XMLHTTP request, would cause us to redirect to SSO. Our Javascript scrapes the new site2pstoretoken which is contained in this HTML and assigns it to the value of the hidden site2pstoretoken already contained in our login.jsp. It does this every 60 seconds (well under the time period in which the Apex session ids seem to expire). Hence, whenever you click Login on your JSP, whether you’ve had it on screen for 30 seconds or 30 days, you will still be submitting a valid encoded Apex URL and will see your app and not just a blank white screen.

Categories: Ajax, ApEx