Mandantenfähige HTML DB-Anwendungen

Arbeitsweise der Virtual Private DatabaseMandantenfähige Anwendungen? Normalerweise zieht eine solche Anforderung sehr großen Aufwand nach sich. Schließlich muss sichergestellt werden, dass jeder Nutzer nur die Daten sieht, zu denen er auch berechtigt ist. 

Mit der Oracle Virtual Private Database und der HTML DB ist diese Anforderung dagegen schnell und einfach implementiert.  Lesen Sie hier, wie sie eine einfache, mandantenfähige HTML DB-Anwendung auf Basis der  bekannten Tabellen EMP und DEPT erstellen.

Die Oracle Virtual Private Database (VPD) ist Teil der Enterprise Edition der Oracle Datenbank. Sie setzt Zugriffsregeln durch, in dem sie an jedes abgesetzte SQL-Kommando implizit eine WHERE-Bedingung anhängt oder die bestehende erweitert. Dieser Vorgang greift bei jedem SQL-Kommando; unabhängig davon, auf welchem Weg es in die Datenbank gelangt. Daher gibt es auch keine Möglichkeit, die VPD-Policies zu umgehen. Wie die SQL WHERE-Klausel erweitert wird, hat der Entwickler selbst in der Hand - er hinterlegt eine Policy-Funktion; diese stellt die zusätzlichen SQL-Bedingungen zusammen und gibt sie an die Datenbank-Engine weiter.

Zur Umsetzung einer mandantenfähigen Anwendung werden zunächst die Zugriffsregeln definiert. Die neue Beispielanwendung soll fünf Benutzer kennen

  • KING darf alle Informationen sehen.
  • SCOTT darf alle Informationen zur Abteilung 10 (ACCOUNTING) sehen.
  • MILLER darf alle Informationen zur Abteilung 20 (RESEARCH) sehen.
  • BLAKE darf alle Informationen zur Abteilung 30 (SALES) sehen.
  • TURNER darf nur seinen eigenen Datensatz sehen.
Diese Privilegien werden in einer neuen Tabelle (MY_USERS) hinterlegt. Nutzen Sie für die folgenden SQL-Skripte am besten den SQL Workshop in der HTML DB:
create table my_users(
userid varchar2(50),
 class varchar2(50),
 depts varchar2(50)
);

insert into my_users values ('SCOTT','DEPTADM','10');
insert into my_users values ('BLAKE','DEPTADM','20');
insert into my_users values ('MILLER','DEPTADM','30');
insert into my_users values ('KING','ADMIN','');

Der erste Schritt zur Umsetzung der VPD ist die Einrichtung eines Session Kontext. Der Session Kontext wird beim Aufbau der Datenbanksitzung initialisiert. Darin werden der Username, das Privileg, welches dieser User hat und die Abteilungen, auf die dieser Benutzer zugreifen kann, für die Dauer der Datenbanksitzung gespeichert. Die Policy-Funktion, welche weiter unten erstellt wird, liest den Session Kontext aus und erstellt oder erweitert anhand der vorgefundenen Informationen die SQL WHERE-Klausel. 

Der nun folgende Code erstellt zunächst den Session Kontext my_context und legt zugleich fest, dass der Kontext nur durch das PL/SQL-Paket my_login_package geändert werden darf. Somit wird sichergestellt, dass niemand den Kontext eigenmächtig manipuliert und so die VPD-Policies aushebelt. 

create or replace context my_context
using my_login_package
/

create or replace package my_login_package
is
  procedure set_context(p_userid in varchar2);
end my_login_package;
/

create or replace package body my_login_package
is
  procedure set_context(p_userid in varchar2) is
   v_class  my_users.CLASS%TYPE := 'USER';
    v_deptno my_users.DEPTS%TYPE := '';
  begin
    for cl in (select class,depts from my_users where userid = p_userid) loop
      v_class := cl.class;
      v_deptno := cl.depts;
    end loop;
    dbms_session.set_context('my_context','class', v_class);
    dbms_session.set_context('my_context','deptno', v_deptno);   
dbms_session.set_context('my_context','userid', p_userid);
  end set_context;
end my_login_package;
/

Im nächsten Schritt legen Sie die eigentliche Policy-Funktion an. Die Funktion liest den Session Kontext mit der SQL-Funktion SYS_CONTEXT aus und erstellt dann die SQL WHERE-Bedingung:

  • Ist das ADMIN-Privileg (Attribut class im Session-Kontext) vergeben, so wird keine WHERE-Bedingung zurückgegeben. Im Ergebnis kann der Nutzer die ganze Tabelle sehen.
  • Wenn das Privileg DEPTADM vergeben ist, so werden die einzelnen  DEPTNO ausgelesen und die SQL-Bedingung DEPTNO in ([DEPTNO], [DEPTNO]) zurückgegeben.
  • Wenn kein Privileg vergeben wurde, so wird eine Einschränkung anhand der Tabellenspalte ENAME (ENAME=[USERID]) vorgenommen.
create or replace function my_policy(
p_schema varchar2, p_object varchar2
) return varchar2 is
  v_sql varchar2(32767);
begin
  if sys_context('my_context','class') = 'ADMIN' then
   null;
  elsif sys_context('my_context','class') = 'DEPTADM' then
    v_sql := ' DEPTNO in ( '||sys_context('my_context','deptno')||')';
  else
    v_sql := ' ENAME = '''||sys_context('my_context','userid')||'''';
  end if;
  return v_sql;
end;
/
Nun sind alle Grundlagen gelegt - Die Aufgabe der Datenbank ist nun, bei jedem SQL-Kommando vor der Ausführung diese Policy-Funktion aufzurufen. Ausgeführt wird dann das durch die zurückgegebene WHERE-Bedingung erweiterte SQL-Kommando. Damit dies auch wirklich geschieht, muss die Policy-Funktion zum Abschluß registriert werden. Dies geschieht mit dem PL/SQL-Paket DBMS_RLS. Ersetzen Sie im folgenden Code bitte [myschema] durch das Datenbankschema, in dem die Tabelle EMP und ihre Policy-Funktion liegen.  Wenn Sie im SQL Workshop den SQL Kommandozeileninterpreter aufrufen (SQL Kommandos), dann sehen Sie das Datenbankschema rechts oben (Abbildung 1).
begin
 DBMS_RLS.ADD_POLICY(
    object_schema => '[myschema]',
    object_name => 'EMP',
    policy_name => 'MY_EMP_POLICY',
    function_schema => '[myschema]',
    policy_function => 'MY_POLICY'
  );
end;
/
Anschließend ist die Virtual Private Database "scharf" geschaltet - ohne die richtigen Privilegien kann man die Tabelle zwar noch selektieren - man sieht jedoch keine Daten mehr.

Nach Aktivierung der VPD: SELECT im SQL Workshop

Abb: 1: Selektieren der Tabelle nach Aktivieren der Virtual Private Database

Legen Sie nun die fünf neuen Benutzer in Ihrem HTML DB Workspace an:

Neue Benutzer im HTML DB Workspace anlegen

Abb. 2: Anlegen der neuen Benutzer im HTML DB Workspace

Legen Sie als nächstes die neue HTML DB-Anwendung an. Eine Seite mit einem Bericht auf die Tabelle EMP reicht aus.

Erstellung einer Anwendung mit einem Bericht auf EMP

Abb: 3: Erstellen einer HTML DB-Anwendung mit einem Bericht auf die Tabelle EMP

Wenn Sie diese neue Anwendung nun starten, werden keine Daten angezeigt, selbst wenn Sie sich als KING angemeldet haben. Grund dafür ist, dass der Session Kontext beim Anmelden an der HTML DB-Anwendung noch nicht initialisiert wurde. Dies geschieht nicht automatisch, es muss vielmehr in den Attributen der HTML DB-Anwendung hinterlegt werden. Navigieren Sie also zu den Anwendungsattributen und dort zur Sicherheit.

Verbinden der HTML DB-Anwendung mit dem Session Kontext

Abb. 4: Verbinden der HTML DB-Anwendung mit dem Session Kontext

Die HTML DB ruft nun automatisch vor jedem Seitenaufbau die Prozedur SET_CONTEXT im Paket MY_LOGIN_PACKAGE auf. Das ist das Paket, welches eingangs erstellt wurde. Übergeben wird die User-ID, mit der sich der Nutzer an der HTML DB-Anwendung angemeldet hat. Daraufhin wird der Session-Kontext initialisiert und der Bericht zeigt nun - abhängig vom angemeldeten Nutzer -  mehr oder weniger Datensätze an:

Bericht: Angemeldet als KING
Bericht: Angemeldet als KING
Bericht: Angemeldet als BLAKE
Bericht: Angemeldet als BLAKE
Bericht: Angemeldet als SCOTT
Bericht: Angemeldet als SCOTT
Bericht: Angemeldet als TURNER
Bericht: Angemeldet als TURNER

Die Nutzung der Virtual Private Database ist nicht auf die Benutzerverwaltung in der HTML DB beschränkt. Die Authentifizierung durch einen LDAP-Server, den Oracle Single Sign On-Service oder ein selbstgeschriebenes Modul ist problemlos möglich.

Zurück zur Community-Seite