Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:apex_authorization_scheme_plsql

Oracle Apex 5 - Authorization Scheme in PL/SQL umsetzen

Die Aufgabe:

Je nachdem in welcher Gruppe ein User ist sollen bestimmte Menü Elemente angezeigt werden und der Anwender soll das entsprechende Admin Formular aufrufen können.

Da es sich um über 50 Stammdaten Tabellen mit wachsender Tendenz handelt, die ganz unterschiedlichen Benutzern zur Verfügung stehen sollen, wird es rein mit Gruppen in Apex ohne weitere Logik schwierig.

Zusätzlich können nicht alle 50 Masken ohne Test in Produktion gestellt werden, d.h. in der Produktion sollen nur die Masken angezeigt werden, die „enabled“ sind.

Die Standard Administratoren sollen das Rechte behalten, ohne Kontrolle im Detail, die Masken aufrufen zu können.

Die Pflege, welche APEX Rolle die Tabelle bearbeiten kann, soll in der Apex Oberfläche bearbeitet werden können.

Lösung:

  • ADMIN Gruppe für die Haupt Administratoren - volle Rechte
  • BUSINESS Gruppe für die Sachbearbeiter, die Sachbearbeiter können sich an der App anmelden
  • FACHBEREICH Gruppe für den Sachbearbeiter, dieser Gruppe regelt die Rechte auf die Maske der Stammdaten Tabelle

In einer Master Tabelle mit allen Informationen über die Stammdaten Masken wird hinterlegt welche FACHBEREICH Gruppe Rechte auf die Maske hat, dies erfolgt über Mitglieder der ADMIN Gruppe. In dieser Tabelle ist auch die ID der Maske hinterlegt mit der die Pflege erfolgen soll, darüber kann wieder zurück auf das Navigationselement für die Maske gefolgert werden.

Damit also ein Sachbearbeiter die Maske sieht, benötigt er die BUSINESS Gruppe und die richtige FACHBEREICH Gruppe, das muss über die Workspace User Verwaltung zuvor zugeordnet werden.

Auf allen Parameter Seiten und allen Navigations List Elementen ist ein Authorization Scheme „PARAM“ hinterlegt.

Über „Shared Components \ Authorization Schemes \ “ wird dieses Scheme als PL/SQL Scheme angelegt.

Nun können wir das ganze individuell mit unseren eigenen Regeln umsetzen.


Code

Die wichtigsten Komponenten des Codes sind:

Aus welchen Kontext wird aufgerufen
   apex_debug.message('app_component_id = ' || :APP_COMPONENT_ID);
   apex_debug.message('app_component_name = ' || :APP_COMPONENT_NAME);
   apex_debug.message('app_component_type = ' || :APP_COMPONENT_TYPE);

Funktioniert aber nur wenn der „Evaluation Point“ des Schemas auf „Once per component“ oder „Always (No Caching)“ steht!!

Welchen Gruppen ist der User zugeordnet
  -- get the user groups
   v_group_list := apex_util.GET_GROUPS_USER_BELONGS_TO(p_username => :APP_USER);
Ist die Komponente vom Typ "APEX_APPLICATION_LIST_ENTRIES", auf was zeigt das Element?
   SELECT REPLACE(regexp_substr(entry_target, '[f?p=&APP_ID.:][[:digit:]]+[:]'),':','')
        INTO v_page_link
        FROM APEX_APPLICATION_LIST_ENTRIES
       WHERE LIST_ENTRY_ID = :APP_COMPONENT_ID;
 
   apex_debug.message('v_page_link for APP_COMPONENT_ID = ' || :APP_COMPONENT_ID || ' = ' || v_page_link);

Der komplette Code

DECLARE
   v_return          BOOLEAN := FALSE;
   v_group_list      varchar2(32000);
   v_page_title      varchar2(256);
   v_business_user   varchar2(256);
   v_table_text      varchar2(32000);
   v_page_link       varchar2(256); 
   v_enabled         varchar2(256); 
BEGIN
   --debug
   apex_debug.message('app_component_id = ' || :APP_COMPONENT_ID);
   apex_debug.message('app_component_name = ' || :APP_COMPONENT_NAME);
   apex_debug.message('app_component_type = ' || :APP_COMPONENT_TYPE);
   -- get the user groups
   v_group_list := apex_util.GET_GROUPS_USER_BELONGS_TO(p_username => :APP_USER);
 
   -- check for parameter user
   IF :APP_COMPONENT_TYPE NOT LIKE 'APEX_APPLICATION_LIST_ENTRIES'
   THEN
      -- check over ADMIN_TABLES if the user can access this page
      BEGIN
         SELECT BUSINESS_USER_GROUP
              , ENABLED
           INTO v_business_user
               ,v_enabled
           FROM ADMIN_TABLES
          WHERE PAGEID = :APP_PAGE_ID;
      exception
         WHEN no_data_found
         THEN
            SELECT PAGE_TITLE
              INTO v_page_title
              FROM APEX_APPLICATION_PAGES
             WHERE PAGE_ID = :APP_PAGE_ID AND APPLICATION_ID = :APP_ID;
 
            v_table_text :=
                  'APP_COMPONENT_NAME := '
               || :APP_COMPONENT_NAME
               || 'APP_COMPONENT_TYPE := '
               || :APP_COMPONENT_TYPE
               || 'APP_COMPONENT_ID := '
               || :APP_COMPONENT_ID;
 
            apex_debug.message('Admin Table not found ::' || v_table_text);
 
 
 
            -- insert to the admin table the missing record
            INSERT INTO ADMIN_TABLES(TABLE_NAME
                                                         ,SHORT_DESC
                                                         ,LONG_DESC
                                                         ,PAGEID)
                 VALUES (substr(v_page_title, 1, 32)
                        ,'Fix :: missing Admin Table Text'
                        ,v_table_text
                        , :APP_PAGE_ID);
 
            commit;
      END;
   ELSE
      -- get the Menü item to this Param table
      -- over the APP_COMPONENT_ID :=
      --select  entry_target,  from APEX_APPLICATION_LIST_ENTRIES where LIST_ENTRY_ID=:APP_COMPONENT_ID
      SELECT REPLACE(regexp_substr(entry_target, '[f?p=&APP_ID.:][[:digit:]]+[:]'),':','')
        INTO v_page_link
        FROM APEX_APPLICATION_LIST_ENTRIES
       WHERE LIST_ENTRY_ID = :APP_COMPONENT_ID;
 
        apex_debug.message('v_page_link for APP_COMPONENT_ID = ' || :APP_COMPONENT_ID || ' = ' || v_page_link);
 
      BEGIN
         IF v_page_link != '-'
         THEN
            SELECT BUSINESS_USER_GROUP
                 , ENABLED
              INTO v_business_user
                 , v_enabled
              FROM ADMIN_TABLES
             WHERE PAGEID = to_number(v_page_link);
         ELSE
            v_business_user := 'n/a';
         END IF;
      exception
         WHEN others
         THEN
            v_business_user := 'n/a';
            apex_debug.message('Error get Page Link Nav Info ::' || sqlerrm);
      END;
   END IF;
 
   ----------
 
   IF instr(v_group_list, 'BUSINESS_USER') > 0
   THEN
      IF instr(UPPER(v_group_list), UPPER(v_business_user)) > 0
      THEN
         v_return := TRUE;
      END IF;
   END IF;
 
 
   -- check for Admin User
 
   IF instr(v_group_list, 'ADMIN_USER') > 0
   THEN
      v_return := TRUE;
   END IF;
 
   -- show only enabled admin tables
   IF :APP_COMPONENT_TYPE = 'APEX_APPLICATION_LIST_ENTRIES' AND  v_enabled = 'N' 
   THEN
    v_return := FALSE;
   END IF;
 
   RETURN v_return;
END;
Darauf achten das der „Evaluation Point“ des Schemas auf „Once per component“ stehen muss!

Quellen

Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
"Autor: Gunther Pipperr"
prog/apex_authorization_scheme_plsql.txt · Zuletzt geändert: 2018/06/13 22:51 von Gunther Pippèrr