|
Datenbank-Rollen in APEX nutzen: Mit Datenbank-Links
Wie die meisten APEX-Anwender wissen, verwendet APEX ein ganz bestimmtes
Sicherheitsmodell. Wenn Sie eine APEX-Seite aufrufen (sei es in einer
Ihrer Applikationen oder in der Entwicklungsumgebung), so wird die zugrundeliegende
Datenbanksitzung, welches der Webserver mit mod_plsql, der neue J2EE-Listener oder
das Embedded Gateway aufbaut, stets mit einem bestimmten, niedrig privilegierten
Benutzerkonto aufgebaut. Beim Embedded Gateway ist das der User ANONYMOUS,
beim mod_plsql typischerweise der APEX_PUBLIC_USER.
Wenn man sich die Privilegien dieses Nutzerkontos näher ansieht, stellt man fest, dass
dieser außer einem CREATE SESSION-Privileg keinerlei Rechte hat. Dennoch können Sie
die Tabellen in Ihrem APEX Workspace betrachten und die PL/SQL-Funktionen, -Prozeduren
und Packages im Schema ausführen.
Das liegt daran, dass die SQL-Kommandos und PL/SQL-Aufrufe nicht direkt
ausgeführt werden, sonderm innerhalb der Application Express-Engine. Wenn Sie
also im SQL-Workshop eine SQL-Abfrage eingeben, wird der PL/SQL-Code der
APEX-Engine aufgerufen. Die Engine läuft im Schema APEX_030200 bei APEX 3.2
oder FLOWS_XXXXXX bei älteren APEX-Versionen. Die APEX-Engine
führt die Anweisungen Ihrer Applikation allerdings nicht mit seinen eigenen Privilegien aus, sondern
es setzt vorher die Privilegien Ihres Workspace Schemas. Abbildung 1, die freundlicherweise
von Niels De Bruijn von der MT AG bereitgestellt wurde, zeigt den Ablauf einer
APEX-Sitzung schematisch.
Abbildung 1: An einer APEX-Sitzung beteiligte Datenbankschemas
Für die Experten:
Ihre SQL-Anweisungen werden am Ende mit dem Paket DBMS_SYS_SQL
ausgeführt. DBMS_SYS_SQL ist undokumentiert, führt
wie DBMS_SQL SQL-Anweisungen aus,
erlaubt im Gegensatz zu diesem aber die Angabe eines Datenbankschemas, mit
dessen Privilegien der Code
ausgeführt werden soll. Das Ergebnis ist, dass die SQL-
und PL/SQL-Anweisungen Ihrer Anwendungen mit den Privilegien des
Workspace-Schemas ablaufen.
Während der ganzen Zeit sind Sie jedoch mit dem niedig privilegierten
Nutzerkonto (ANONYMOUS bzw.
APEX_PUBLIC_USER) verbunden. Den Unterschied können
Sie im SQL Workshop sehr gut nachvollziehen -
legen Sie dazu mit folgender
SQL-Anweisung eine View an:
Abbildung 2 zeigt eine Abfrage auf diese View. Man erkennt, dass die
Datenbankverbindung selbst als ANONYMOUS erfolgt ist,
das SQL jedoch
mit den Privilegien von FSMASTER abläuft.
Abbildung 2: SESSION_USER vs. CURRENT_USER in einer APEX-Sitzung
Die erste wichtige Feststellung im APEX-Umfeld ist also schonmal die, dass
alle SQL- und PL/SQL-Aufrufe nicht direkt in der Datenbanksitzung ausgeführt werden,
sondern von den PL/SQL-Funktionen der APEX-Engine, welche sicherstellt, dass
die Privilegien des Workspace-Schemas angewendet werden. Dadurch wird
der Code mit den Privilegien ausgeführt, die Sie erwarten - hat aber den
Nebeneffekt, dass alle
Rollen, die Ihrem Workspace-Schema zugewiesen sein könnten, abgeschaltet sind.
Manchmal kommt es allerdings vor, dass man ein Kommando gerne im gleichen
Kontext ablaufen lassen würde, wie es in SQL*Plus oder im SQL Developer wäre ...
- ... also mit allen Rollen, die dem Workspace-Schema zugewiesen sind ...
- ... und mit einer Datenbanksitung, die effektiv mit dem Workspace-User
aufgebaut wurde. Es gibt in der Oracle-Datenbank die eine oder andere Komponente, die
zum einwandfreien Betrieb eben eine solche Datenbankverbindung braucht.
Die Lösung ist überraschend einfach!
- Legen Sie einen Datenbank-Link an, der auf das gleiche Schema in der gleichen Datenbank
verweist: Wenn das Datenbankschema also FSMASTER heißt, legen Sie den Link wie folgt an (der Datenbank-Link soll LOOPBACK heißen; Sie können den Namen allerdings frei wählen).
- Legen Sie eine Prozedur an, die ein beliebiges SQL-Kommando entgegennimmt und
ausführt. Wenn Sie die Rollen, die Ihrem Schema zugewiesen sind, benötigen,
ist es wichtig, dass Sie die Prozedur mit AUTHID CURRENT_USER anlegen. Das folgende
Beispiel ist bewusst einfach gehalten; natürlich können Sie auch eine Funktion draus
machen, die evtl. erhaltene Rückgabewerte entgegennimmt und wiederum an den
APEX-Prozeß weiterreicht.
Auf die Gefahren einer SQL Injection soll hier bewußt nicht eingegangen werden - wenn Sie dies in Applikationen verwenden, sollten Sie sicherstellen, dass durch das EXECUTE IMMEDIATE keine SQL-Injection-Löcher entstehen. Zum Thema gibt es einen eigenen Community-Tipp.
Und das war's auch schon. Wenn Sie nun für die Ausführung eines PL/SQL-Prozesses
aktivierte Rollen benötigen, führen Sie den Code einfach
über diese Prozedur aus.
Mit diesem Konstrukt wird die Prozedur exec nicht "lokal", sondern "entfernt"
über den Database Link aufgerufen - was die gleiche Prozedur ist. Allerdings
wird eine andere Datenbanksitzung verwendet - diese ist keine APEX-Sitzung mehr und
mit dem "richtigen"
Datenbankuser aufgebaut. Das zeigt auch der erneute Test mit der View aus
Abbildung 2. Fragt man diese View über den Datenbanklink ab, so erkennt man,
dass diese Datenbanksitzung nun tatsächlich mit dem Workspace-Schema verbunden ist.
Abbildung 3: SESSION_USER vs. CURRENT_USER in einer Sitzung über einen Datenbanklink
Wenn PL/SQL-Prozedur exec (oder eine andere) nun noch mit
AUTHID CURRENT_USER angelegt wurde, so
bleiben die Rollen, die dem Workspace-User zugewiesen wurden, aktiv. Auf diesem
Weg ist es also durchaus möglich, einem Datenbankuser zugewiesene Rollen
in APEX-Anwendungen nutzen zu können.
Einen solchen Datenbank-Link können Sie für Berichte nutzen. Auch hierzu ein
Beispiel: Geben Sie dem Workspace-User auf einem Testsystem mal die Rolle
SELECT_ANY_DICTIONARY; diese beinhaltet - wie der Name schon sagt -
SELECT-Privilegien auf alle Tabellen des Data Dictionary (auch auf solche, auf
die sonst nur der DBA Zugriff hat). Eine dieser Dictionary-Views ist DBA_TABLES;
darin stehen Informationen über alle Tabellen in der Datenbank.
Loggen Sie sich danach in Ihrem APEX Workspace ein und versuchen Sie, in
einer Applikation einen Bericht auf die View DBA_TABLES zu erzeugen. Sie
werden feststellen, dass dies so einfach nicht geht (Abbildung 4).
Abbildung 4: Ein Berichts SQL, welches Rollen benötigt, funktioniert in APEX erstmal nicht
Wenn Sie jedoch das Berichts-SQL umändern in ...
... dann können Sie den Bericht erzeugen und ganz normal verwenden.
Einige Restriktionen sollen aber nicht unerwähnt bleiben. So gibt es Beschränkungen,
die Datentypen CLOB, BLOB,
XMLTYPE oder benutzerdefinierte Datentypen über
einen Datenbanklink zu verwenden. Wenn also ein BLOB an die Prozedur übergeben
werden soll, funktioniert dies über den Datenbanklink nicht so einfach. Da der
Link jedoch ins gleiche Schema auf der gleichen Datenbank zeigt, lässt sich
dies einfach umgehen, indem man den BLOB oder CLOB in eine Tabelle zwischenspeichert.
Alles in allem sind die Datenbank-Links eine gute Möglichkeit, PL/SQL-Code
oder SQL-Anweisungen in APEX so auszuführen wie in SQL*Plus oder dem SQL Developer.
Mit dem Datenbank-Link bekommt man eine Datenbanksession, die effektiv mit
dem Workspace-Schema arbeitet und nicht mit APEX_PUBLIC_USER
oder ANONYMOUS. Außerdem
können, wenn die verwendeten PL/SQL-Prozeduren mit AUTHID CURRENT_USER angelegt
werden, evtl. vorhandene Rollenkonzepte weitergenutzt werden.
Zurück zur Community-Seite
|