This blog will explain how to proceed in order to redirect all the application pages to one single page, prior to their processing and rendering, with Oracle APEX 4.0 and above.

In some cases, like security checks, you may want to redirect all calls of any page in your APEX application to one single page whith particular processing before the target page is rendering or even processing.

I ran into this need again, recently while developing some application.

The problem to solve:

Application user has to change his password after first login or password reset. No other page than password change should be accessed until successful change. This page is part of standard administration, as user can also choose to change his password at any time. It therefore contains already links to navigate within the application, which needs to be prevented. In addition any page call within the application, from direct URL entry, must be prevented as well (no cheating allowed).

Where would you put some code, in APEX, which needs to be accessed by all pages in the application?

Natural answer would be Page 0, also known as Global Page.

So what? Let’s put some branch into the ‘Before Header’ part of the global page, which would redirect as soon as any page rendering starts, preventing the display of the current page.

Unfortunately, this doesn’t work…

Why? Simply because APEX doesn’t handle it. The first indicator is that you can’t access any branching in the ‘Before Header’ section of the global page, unlike any normal page.

GlobalPage_NoBranch_Compare

You have to trick, using the ‘Create – Add a page control to this page’ wizard, to add such kind of branching. So, you shouldn’t do it…

What else can we do?

APEX offers another nice feature called by any page of the application: Application Processes.

And that’s the key. The branching is not happening as easy as when done declaratively in a page, but adding those few lines of PL/SQL in the process will make it:

htp.init;
  owa_util.redirect_url(‘f?p=&APP_ID.:CHGPWD:&SESSION.’);
apex_application.stop_apex_engine;

In order to work you also need to tell him when to run. In our case ‘On Load: Before Header (page template header)’.

ApplicationProcess_start_point

This application process will do the job and even overeager, because the target page itself will loop into death. So you need to set some condition on that process, in order to NOT call it when the current page is the target page. In my case I have also added the login page of the application as user is allowed to get back to it even though the password was not changed. In order to combine condition related to page and user state verification, execution of the application process is linked to the result of a function returning a boolean.

Condition

Below the code of the function called. To make it nice and avoid having hard coded page numbers, you can use page aliases and retrieve the page number as shown:

FUNCTION is_change_password_required
RETURN BOOLEAN IS
v_username VARCHAR2(30);
v_chg_pwd_required BOOLEAN;
v_found NUMBER;
BEGIN
v_chg_pwd_required := TRUE;
v_username := NVL(v(‘APP_USER’), USER);

— Check if current page is Login or change password
— to enforce login and avoid looping on change password
SELECT COUNT(*) INTO v_found
      FROM apex_application_pages
      WHERE application_id = v(‘APP_ID’)
        AND page_id = v(‘APP_PAGE_ID’)
        AND page_alias IN (‘LOGIN’, ‘CHGPWD’);

IF v_found > 0 THEN
        v_chg_pwd_required := FALSE;
      ELSE
        v_chg_pwd_required := is_new_or_reset_password(v_username);
      END IF;
     
      RETURN v_chg_pwd_required;
     
    END is_change_password_required;

I hope you will enjoy this solution for your own password change management or other purpose.