Anwendungsbenutzer eindeutig identifizieren
von Heinz-Wilhelm Fabry, ORACLE Deutschland GmbH

Die Architektur moderner Anwendungen sieht häufig sehr ähnlich aus: Ein Benutzer identifiziert sich auf der Middletier gegenüber der Anwendung. Die Anwendung selbst arbeitet dann entweder über einen Connection Pool mit der Datenbank oder es gibt, wie bei Oracle Application Express (Apex) oder den großen Anwendungspaketen von Oracle (Siebel, Oracle E-Business Suite, Peoplesoft...) und SAP, auf der Datenbankseite nur einen einzigen Anwender. Dieser führt alle Abfragen oder Datenmanipulationen für den Endanwender aus. In beiden Fällen - Connection Pool oder einzelner Anwendungsbenutzer - ist auf der Datenbank nicht mehr ohne Weiteres festzustellen, welcher Endanwender tatsächlich für eine Abfrage oder Manipulation verantwortlich ist.

Immer häufiger wird aber aus Gründen der Sicherheit und Nachvollziehbarkeit verlangt, dass nicht nur anwendungsseitig, sondern z.B. auch im Rahmen des Datenbankauditing nachweisbar sein muss, wer genau welche Daten abfragt oder ändert. Deshalb stellt sich die Frage, wie eine Anwendung mit den oben beschriebenen Eigenschaften Informationen über konkrete Benutzer an die Datenbank übergeben kann.

Die Oracle Datenbank bietet für diese Anforderung eine sehr einfache Möglichkeit. Sie setzt lediglich voraus, dass die auf der Middletier laufende Anwendung eine Umgebungsvariable manipuliert, den CLIENT_IDENTIFIER. Wie der CLIENT_IDENTIFIER in den eigenen Anwendungen zu verwenden ist, wird in diesem Tipp dargestellt. Übrigens verwendet Peoplesoft Tools in der Version 8.50 den CLIENT_IDENTIFIER bereits, und auch in der Oracle E-Business Suite soll er schon bald standardmäßig verfügbar sein.

Zunächst soll die Umgebung kurz skizziert werden, die den Hintergrund für die Beispiele dieses Beitrags liefert. Es handelt sich um eine Enterprise Edition der Datenbank in der Version 11.2.0.1. Der Parameter AUDIT_TRAIL ist auf den Wert XML,EXTENDED gesetzt. Die Einstellung bewirkt, dass die Audit Daten im XML Format in eine Datei auf das Betriebssystem geschrieben werden. Das XML Format erlaubt - anders als das oraclespezifische Format, das durch das Setzen des Parameters AUDIT_TRAIL auf OS entsteht - auch das Erfassen des vollständigen SQL Texts eines Statements. Der Aufzeichnung auf der Betriebssystemebene sollte in der Regel der Vorzug gegeben werden, weil damit die Performance einer produktiv genutzten Datenbank insgesamt weniger beeinflußt wird als durch das Schreiben der Audit Daten in die Systemtabelle AUD$. Die Dateien mit den Audit Daten werden in dem Verzeichnis abgelegt, auf das der Initialisierungsparameter AUDIT_FILE_DEST zeigt. Für die Tabelle EMP des Benutzers SCOTT ist das public synonym EMP definiert. Scott hat für die Tabelle EMP das Auditing mit folgendem Befehl aktiviert:

AUDIT select, insert, update, delete ON emp
Die Audit Informationen in der XML Datei können über die View DBA_COMMON_AUDIT_TRAIL abgefragt werden. Die View enthält über 40 Spalten, von denen hier nur die Spalten DB_USER, CLIENT_ID, OBJECT_NAME und SQL_TEXT betrachtet werden. Nachdem über eine Anwendung zwei verschiedene Anwender Abfragen und Änderungen auf der Tabelle durchgeführt haben, ergibt eine Abfrage auf die View DBA_COMMON_AUDIT_TRAIL folgendes Bild (die Spalten sind mit dem Befehl COLUMN für die Ausgabe formatiert worden)
SELECT db_user, object_name, client_id, sql_text FROM dba_common_audit_trail
WHERE object_name = 'EMP';

DB_USER  OBJECT_NAME  CLIENT_ID  SQL_TEXT
-------- ------------ ---------- -----------------------------------------------
APPUSER  EMP                     SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp
APPUSER  EMP                     UPDATE emp SET sal = sal + 1 WHERE empno = 7934
APPUSER  EMP                     SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp WHERE empno = 7934
APPUSER  EMP                     UPDATE emp SET sal = sal - 1 WHERE empno = 7934
Die Spalte DB_USER enthält den Namen des Anwendungsbenutzer, CLIENT_ID enthält keinen Eintrag.

Die Anwendung wird nun modifiziert. Sie erfasst jetzt den Namen des Anwendungsbenutzers in der Variablen ENDANWENDER und weist bei jedem Connect den Wert dieser Variablen der Umgebungsvariablen CLIENT_IDENTIFIER zu. Das passiert mit der Prozedur SET_IDENTIFIER aus dem Package DBMS_SESSION. Eigentümer des Package ist zwar SYS, allerdings ist das Package für den Benutzer PUBLIC ausführbar. Die Ausführung erfolgt mit den Privilegien des aufrufenden Anwenders. Der Prozedur SET_IDENTIFIER kann nur ein Wert vom Typ VARCHAR2 übergeben werden.
-- Variable ENDANWENDER wird durch die Anwendung gesetzt und dann mit DBMS_SESSION weiterverarbeitet.
--
DBMS_SESSION.SET_IDENTIFIER(endanwender);
Die Variable ENDANWENDER muß nicht unbedingt den Namen des jeweiligen Anwendungsbenutzers enthalten, sondern kann auch bis zur maximalen Länge von 64 Bytes mit jeder beliebigen anderen oder auch zusätzlichen Zeichenkette gefüllt werden, die die eindeutige Identifizierung eines Anwenders ermöglicht, z.B. mit der Personalnummer.

Erneut arbeiten die Anwender mit der Anwendung. Dass sie mit einer leicht modifizierten Anwendung arbeiten, bemerken sie nicht. Wird die View DBA_COMMON_AUDIT_TRAIL abgefragt, sieht das Ergebnis nun folgendermassen aus:
SELECT db_user, object_name, client_id, sql_text FROM dba_common_audit_trail
WHERE object_name = 'EMP';

DB_USER  OBJECT_NAME  CLIENT_ID  SQL_TEXT
-------- ------------ ---------- -----------------------------------------------
APPUSER  EMP                     SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp
APPUSER  EMP                     UPDATE emp SET sal = sal + 1 WHERE empno = 7934
APPUSER  EMP                     SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp WHERE empno = 7934
APPUSER  EMP                     UPDATE emp SET sal = sal - 1 WHERE empno = 7934
APPUSER  EMP          Fabry      SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp
APPUSER  EMP          Fabry      UPDATE emp SET deptno = 40 WHERE empno = 7900
APPUSER  EMP          Schwinn    SELECT empno, ename, job, mgr, hiredate, sal,
                                 comm, deptno FROM emp WHERE empno = 7900
APPUSER  EMP          Schwinn    UPDATE emp SET deptno = 30 WHERE empno = 7900
Die ersten vier Einträge enthalten noch die Audit Einträge der ersten Aktionsreihe. Die nächsten Einträge enthalten jetzt allerdings in der Spalte CLIENT_ID die Namen der Anwendungsbenutzer. Hier wird deutlich, dass der Wert, den die Anwendung für den CLIENT_IDENTIFIER setzt, automatisch mit den übrigen Audit-Informationen gespeichert wird und in der Spalte CLIENT_ID der entsprechenden System Views (DBA_COMMON_AUDIT_TRAIL, DBA_AUDIT_TRAIL und andere) angezeigt wird.

Damit ist das Ziel erreicht, Anwender, die sich nur der Middletier gegenüber authentifizieren, im Audit Trail der Datenbank eindeutig zu identifizieren. Erwähnenswert ist sicherlich, dass dies nicht nur bei der Verwendung von PL/SQL möglich ist, sondern auch mit dem Oracle Call Interface (OCI) oder dem JDBC-Treiber.

In der Anwendung sollte die Information im CLIENT_IDENTIFIER in der Regel nach Beendigung einer Aktion für die nächste Session explizit freigegeben werden. Dies geschieht mit der Prozedur CLEAR_IDENTIFIER aus dem Package DBMS_SESSION. Die Prozedur kann nur ohne Parameter aufgerufen werden und löscht den CLIENT_IDENTIFIER der aktuellen Session.
DBMS_SESSION.CLEAR_IDENTIFIER;
Abschliessend sei noch einmal darauf hingewiesen, dass einer der Vorteile der beschriebenen Vorgehensweise darin besteht, dass die Informationen zum Endanwender Teil des Audit Trail werden. Dort genießen sie schon einen Schutz, der über das hinausgeht, was beispielsweise durch eine applikationsspezifische Protokollierung in eigens dafür angelegten Tabellen erreicht werden kann. Für noch höhere Sicherheitsanforderungen könnten diese Informationen dann sogar noch automatisch in das Data Warehouse für Audit Daten übertragen werden, den Audit Vault. Aber natürlich kann man sich die Information auch in anderen Zusammenhängen nutzbar machen.

Weitere und alternative Anregungen zu vergleichbaren Fragestellungen bieten die beiden Beiträge der Apex-Community Mandantenfähige HTML-Anwendungen und Wer war das ...? Auditing in APEX-Anwendungen ...? sowie ein Blog-Beitrag von Carsten Czarski. Die vollständigen Informationen zum Arbeiten mit DBMS_SESSION finden sich im Handbuch PL/SQL Packages and Types Reference 11g Release 2 (11.2).

Zurück zur Community-Seite