www.Gerhard-Raabe.de
  Oracle
 
 
Back   User
 
Copyright: Der nachfolgende Code ist frei verfügbar, solange er nicht kommerziell verwendet wird! Falls er so wie veröffentlicht, in Teilen oder abgewandelt zum Einsatz kommt, würde ich mich sehr über eine kurze E-Mail freuen.
 
Datenmodel: User
 
Beschreibung: In der Regel reicht die User-Verwaltung einer Datenbank nicht aus, um die Zugriffsberechtigungen innerhalb einer auf die Datenbank zugreifenden Application steuern zu können. Daher muß häufig eine eigene Userverwaltung eingerichtet werden.

Die hier vorgestellte User-Verwaltung ermöglicht es User in User-Gruppen zusammenzufassen und diesen User-Gruppen Rechte (Permissions) zuzuweisen. Die zur notwendigen Verwaltung und Nutzung benötigten Proceduren/Funktionen befinden sich in dem Package users.

Da in einigen Branchen (z.B. Banken/Versicherungen) sehr viel Wert auf die Nachvollziehbarkeit von Änderungen gelegt wird, werden alle Berechtigungsänderungen über Trigger in History-Tabellen protokolliert.

Hinweis: Dieses Berechtigungskonzept ist so in einem von mir durchgeführten Projekt vom Bundesamt für das Finanzwesen (Bafin) abgenommen worden.
 
Application-Login: In einer klassischen Client-Server Architektur sollten dem User aus Sicherheitsgründen möglichst wenig Rechte direkt auf der Datenbank eingeräumt werden. Stattdessen sollten die Tätigkeiten des Users, die sich aus den Arbeitsprozessen ergeben, in einer guten Ablaufführung der Client-Applikation kontrolliert durchgeführt werden. Dazu benötigt die Applikation mehr Rechte als man in der Regel dem einzelnen Usern zugestehen möchte.

Daher bietet es sich an, die Anmeldung der Client-Applikation an die Datenbank mit einem den für den User nicht sichtbaren Applikations-Login durchzuführen. Die Rechte, die der sich jeweils anmeldende User dann erhält, werden dann über ein wie hier vorgestelltes Berechtigungskonzept verwaltet.

In einem sicherheitsrelevantem Umfeld (Banken/Versicherungen etc.) wird darüberhinaus auch eine strikte Trennung zwischen Entwicklungs- und Produktonssystem gefordert. Login und Passwort eines solchen Applikations-Login dürfen dem Entwickler nicht bekannt sein, sondern müssen vom Administrator der Produktionsumgebung frei wähl- und änderbar sein, ohne das der Entwickler davon Kenntnis erhalten darf. Auch darf der Applikations-Login nicht unverschlüsselt auf dem Client hinterlegt werden. Dies wäre z.B. im Falle einer Passwort-Änderung ein erheblicher adminstrativer Aufwand, da es ja auf jedem Client geändert werden muß. Darüberhinaus könnte sich der User so auch ganz leicht die Zugangsparameter und somit die erweiterten Berechtigungen des Applikations-Login besorgen. Es ist also darauf zu achten das:
  • dem Entwickler kein Account bekannt ist, der ihm relevanten Zugriff auf die Produktionsumgebung gewährt
  • der User keine Möglicheiten erhält sich die Accountdaten für den Applikations-Account mit seinen erweiterten Berechtigungen zu beschaffen
  • der Administrator an zentraler Stelle freie Verfügungsgewalt über die Accountdaten des Applikations-Account erhält
Bei dem hier vorgestellten Konzept erhält der Entwickler lediglich Kenntnis über die Account-Daten eines anonymisierten Anmelde-Account, der nur die Ausführrechte für die Datenbankfunktion:

 
FUNCTION get_application_login
(
  login IN OUT tuse_user.use_login%TYPE,
  password IN OUT tuse_user.use_password%TYPE
)
RETURN INTEGER;

 

hat. Die Accountdaten für diesen stark eingeschränkten Anmelde-Account kann der Entwickler z.B. fest im Code (oder entsprechend verschlüsselt im Konfigurationsfile der Client-Applikation) hinterlegen. Da dieser Anmelde-Account faktisch 'rechtelos' ist, kann auf eine Änderung des Passwortes in vorgeschriebenen Zeitintervallen verzichtet werde.

Die Client-Applikation führt nun die folgenden Schritte aus:

  • Im ersten Schritt meldet sich die Client-Applikation nun mit diesem Anmelde-Account an die Datenbank an.
  • Die Client-Applikation fragt nun die personalisierten Accountdaten des Users ab.
  • Mit den personalisierten Accountdaten des Users ruft die Client-Applikation die Funktion users.get_application_login auf.
  • Die Funktion verifiziert nun die personalisierten Accountdaten gegen die in tuse_user hinterlegten Daten.
  • Wird die Zugangsberechtigung des Users von der Funktion bestätigt, dann übergibt sie die Account-Daten für den Applikations-Login an die Client-Applikation.
  • Die Client-Applikation melde sich mit dem Anmelde-Account von der Datenbank ab.
  • Anschließend meldet sie sich mit den Daten des Applikations-Account erneut an und hat damit nun dessen erweiterten Berechtigungen, ohne das User und Entwickler von den Accountdaten Kenntnis erhalten müssen.

    Innerhalb der Client-Applikation können nun die userabhängigen Rechte (Permissions) über das hier vorgestellte Berechtigungskonzept verwaltet und gesteuert werden. Dazu verwendet die Client-Applikation die Datenbankfunktion users.check_permission.
Unabhängig vom Administrator der Produktionsdatenbank können jetzt nur Entwickler und User zusammen an die Daten des Anmelde-Accounts gelangen. Da es sich hier aber um klar getrennte Aufgabengebiete handelt ist hier die nötige Funktionstrennung eingehalten.
 
Vorraussetzungen: Zur Ablage einiger Konfigurationsparameter wird das Package Parameter benötigt. Die folgenden Werte werden dort hinterlegt:

 Parametergruppe   Parameter   Wert   Beschreibung 
 User-Login   Min.Password-Length   8  Minimale Passwortlänge 
 Password-History   10   Anzahl der historischen Passwörter die nicht mit einem neuen Passwort übereinstimmen dürfen 
 Max.-Failed-Login   3   Maximale Anzahl der erlaubten fehlerhaften Logins 
 PW-Expired-Time   90   Zeit in Tagen, nach denen das Passwort abläuft 
 App.-Login   UNKNOWN   Login mit umfangreichen Berechtigungen für die Applikation (siehe auch: Application-Login) 
 App.-Password   UNKNOWN   Passwort für den Applikation-Login (siehe auch: Application-Login) 
 
Tabellen: tuse_user

Enthält die notwendigen Benutzer-Informationen wie Name, Login, Password, etc.

 Spalte   Datentyp   Comment 
 use_id   NUMBER(6)   Identifier 
 use_name   VARCHAR2(32)   Name des Users 
 use_login   VARCHAR2(12)   Login des Users 
 use_password   VARCHAR2(16)   Password des Users in MD5 kodiert 
 use_password_changed   TIMESTAMP   letze Änderungsdatum des User-Password 
 use_password_never_expired   VARCHAR2(4) 
 no   :   Password läuft nach einer voreingestellten Zeit ab 
 yes   :   Password läuft nie ab 
 use_status   VARCHAR2(16)   Login-Status des User: 
 locked   :   User locked 
 pw_must_changed   :   User muß Password bei der nächsten Anmeldung ändern 
 active   :   User active 
 use_email   varchar(64)   E-Mail Adresse des Users 
 use_email_active   VARCHAR2(8) 
 active   :   E-Mail active 
 inactive   :   E-Mail inactive 


tusg_user_group

Enthält die Definition der Usergruppen.

 Spalte   Datentyp   Comment 
 usg_id   NUMBER(6)   Identifier 
 usg_label   VARCHAR2(16)   Name der Usergruppe 
 usg_description   VARCHAR2(64)   Beschreibung der Usergruppe 


tupe_user_permission

Enthält die Definition der Berechtigungen.

 Spalte   Datentyp   Comment 
 upe_id   NUMBER(6)   Identifier 
 upe_label   VARCHAR2(16)   Name der Berechtigung 
 usg_description   VARCHAR2(64)   Beschreibung der Berechtigungen 


tuga_use_usg_assign

Ordnet User Usergruppen zu.

 Spalte   Datentyp   Comment 
 uga_use_id   NUMBER(6)   Referenz-ID zu [tuse_user] (User) 
 uga_usg_id   NUMBER(6)   Referenz-ID zu [tusg_user_group] (Usergruppen) 


tupa_usg_upe_assign

Ordnet Usergruppen Berechtigungen zu.

 Spalte   Datentyp   Comment 
 upa_usg_id   NUMBER(6)   Referenz-ID zu [tusg_user_group] (Usergruppen) 
 upa_upe_id   NUMBER(6)   Referenz-ID zu [tupe_user_permissions] (Berechtigungen) 


tulg_user_login_log

Enthält für jeden User ein Protokoll über jeden erfolgreichen oder fehlerhaftem Login.

 Spalte   Datentyp   Comment 
 ulg_use_id   NUMBER(6)   Referenz-ID zu [tuse_user] (User) 
 ulg_datetime_login   TIMESTAMP   Zeitpunkt des versuchten Logins 
 ulg_status   VARCHAR2(8)   Ergebnis des Loginprozesses: 
 ok   :   Login war erfolgreich 
 failed   :   Login war nicht erfolgreich 


tuph_user_pw_history

Enthält die historisierten Passwords zur Kontrolle auf wiederverwendete Passwords.

 Spalte   Datentyp   Comment 
 uph_use_id   NUMBER(6)  Referenz-ID zu [tuse_user] (User) 
 uph_password_changed   TIMESTAMP   Änderungsdatum des User-Password 
 uph_password   VARCHAR2(48)   historisiertes Password des Users in MD5 kodiert 


Historietabellen (h...)

Änderungen auf den Berechtigungstabellen werden über Trigger in Historietabellen protokolliert:

 Tabelle   Trigger   Historietabelle 
 tuse_user   trg_use_user   huse_user  
 tusg_user_group   trg_usg_user_group   husg_user_group 
 tuga_use_usg_assign   trg_uga_use_usg_assign   huga_use_usg_assign 
 tupa_usg_upe_assign   trg_upa_usg_upe_assign   hupa_usg_upe_assign  

Zusätzlich zu den Spalten der Arbeitstabellen enthalten die Historietabellen noch die Information über den User der die Änderung vorgenommen hat, dem Änderungszeitpunkt und dem ausführenden SQL-Statement. Wegen der besseren Übersicht werden dabei nur die Spalten befüllt, deren Inhalt geändert wurde. Alle anderen werden mit NULL befüllt.

 Spalte   Datentyp   Comment 
   .      .      . 
   .      .      . 
   .      .      . 
 ..._user   VARCHAR2(32)   User. der die Änderung durchgeführt hat 
 ..._timestamp   TIMESTAMP   Zeitpunkt der Änderung 
 ..._action   CHAR(1)   SQL der Änderung (I = Insert, U = Update, D = Delete) 
 
Proceduren/
Funktionen:
Die Proceduren / Funktionen befinden sich im Package users:


add_user

 
FUNCTION add_user
(
  name IN tuse_user.use_name%TYPE,
  login IN tuse_user.use_login%TYPE,
  password IN OUT tuse_user.use_password%TYPE,
  password_never_expired IN tuse_user.use_password_never_expired%TYPE DEFAULT 'no',
  status IN tuse_user.use_status%TYPE DEFAULT 'active',
  email IN tuse_user.use_email%TYPE DEFAULT NULL,
  email_active IN tuse_user.use_email_active%TYPE DEFAULT 'inactive',
)
RETURN tuse_user.use_id%TYPE;

 

Fügt einen neuen User in das Berechtigungssystem ein. Wird kein Passwort übergeben, dann wird mittels der packageeigenen, nicht öffentlichen Funktion create_default_password ein Passwort erzeugt und zurückgegeben. (Hinweis: Die Werte email und email_active füllen hier nur die Spalten in der Tabelle tuse_user. Das Package users benötigt diese Werte ansonsten nicht.)

Returnwerte:
>0  =  add login successfull, returns the User-ID (use_id)
0  =  login exists
-1  =  password not confirm to the password-rules


change_password

 
FUNCTION change_password
(
  login IN tuse_user.use_login%TYPE,
  password_old IN tuse_user.use_password%TYPE,
  password_new IN tuse_user.use_password%TYPE
)
RETURN INTEGER;

 

Ändert das Passwort für einen bestehenden Login (login). Dabei wird die Änderung nur zugelassen, wenn das neue Passwort den definierten Passwort-Regeln entspricht. Die Passwort-Regeln können in der nicht öffentlichen Funktion check_password_roles den jeweiligen Erfodernissen angepaßt werde. Desweiteren wird überprüft, ob das neue Passwort ungleich dem alten Passwort ist und auch nicht gleich einer festgelegten Anzahl der zuletzt benutzten Passwörtern entspricht. Die Anzahl der überprüften historischen Passwörtern wird in der Parameter-Tabelle hinterlegt.

Returnwerte:
1  =  successful
0  =  login not defined
-1  =  password(new) not confirm to the password-rules
-2  =  password(old) incorrect
-3  =  password(new) = Password(old)
-4  =  password(new) = one of the last X Passwords in the Password-History


check_login

 
FUNCTION check_login
(
  login IN tuse_user.use_login%TYPE,
  password IN tuse_user.use_password%TYPE
)
RETURN INTEGER;

 

Überprüft, ob ein User mit dem login und password existiert. Dabei wird auch abgeprüft, ob das Passwort abgelaufen ist und geändert werden muß. Wird die Funktion zu einem Login mehrmals hintereinander mit einem falschen Passwort aufgerufen (sie Anzahl der erlaubten Fehlanmeldungen wird in der Parameter-Tabelle hinterlegt), dann wird der Account gesperrt.

Returnwerte:
1  =  successful
0  =  login not defined
-1  =  password incorrect
-2  =  login successful but password expired (older then X days), please change it
-3  =  login successful but password must change, please change it
-4  =  login locked
-5  =  login locked after X failed logins


get_application_login

 
FUNCTION get_application_login
(
  login IN OUT tuse_user.use_login%TYPE,
  password IN OUT tuse_user.use_password%TYPE
)
RETURN INTEGER;

 

Überprüft, ob ein User mit dem login und password existiert. War der Login erfolgreich werden login und password mit den aus der Parameter-Tabelle ausgelesenen Werten zurückgegeben. Siehe dazu auch: Application-Login

Returnwerte:
1  =  successful
0  =  login not defined
-1  =  password incorrect
-2  =  login successful but password expired (older then X days), please change it
-3  =  login successful but password must change, please change it
-4  =  login locked
-5  =  login locked after X failed logins


set_user_group

 
FUNCTION set_user_group
(
  group_id IN tusg_user_group.usg_id%TYPE DEFAULT NULL,
  group_label IN tusg_user_group.usg_label%TYPE DEFAULT NULL,
  group_description IN tusg_user_group.usg_description%TYPE DEFAULT NULL
)
RETURN INTEGER;

 

Wenn die Gruppen-ID group_id = NULL ist, dann wird eine neue User-Gruppe hinzugefügt. Ist die Gruppen-ID group_id != NULL, dann wird der bestehende Eintrag entsprechend der übergebenen Werte modifiziert.

Returnwerte:
>0  =  add group successfull, returns the Group-ID (usg_id)
-1  =  new group can not be created if label is NULL
-2  =  new group can not be created because there is a group with this label
-3  =  group can not be updated because there is a group with this label
-4  =  cannot update group, because the ID does not exists


set_user_permission

 
FUNCTION set_user_permission
(
  permission_id IN tupe_user_permission.usg_id%TYPE DEFAULT NULL,
  permission_label IN tupe_user_permission.usg_label%TYPE DEFAULT NULL,
  permission_description IN tupe_user_permission.usg_description%TYPE DEFAULT NULL
)
RETURN INTEGER;

 

Wenn die Berechtigungs-ID permission_id = NULL ist, dann wird eine neue User-Berechtigung hinzugefügt. Ist die Berechtigungs-ID permission_id != NULL, dann wird der bestehende Eintrag entsprechend der übergebenen Werte modifiziert.

Returnwerte:
>0  =  add permission successfull, returns the Permission-ID (upe_id)
-1  =  new permission can not be created if label is NULL
-2  =  new permission can not be created because there is a permission with this label
-3  =  permission can not be updated because there is a permission with this label
-4  =  cannot update permission, because the ID does not exists


assign_user_to_group

 
FUNCTION assign_user_to_group
(
  login IN tuse_user.use_login%TYPE,
  group_label IN tusg_user_group.usg_label%TYPE,
  assign IN INTEGER DEFAULT 1
)
RETURN INTEGER;

 

assign  =  1  :  Die User-Gruppe group_label wird dem User login zugeordnet
assign  =  0  :  Wenn Die User-Gruppe group_label dem User login zugeordnet ist, dann wird sie aufgehoben. Ist Die User-Gruppe group_label dem User login nicht zugeordnet ist, dann wird sie zugeordnet.
assign  =  -1  :  Die Zuordnung User-Gruppe group_label / User login wird aufgehoben

Returnwerte:
1  =  successful
0  =  no changes, because mapping is like status in assign
-1  =  login does not exist
-2  =  group does not exist


assign_permission_to_group

 
FUNCTION assign_permission_to_group
(
  permission_label IN tupe_permission.upe_label%TYPE,
  group_label IN tusg_user_group.usg_label%TYPE,
  assign IN INTEGER DEFAULT 1
)
RETURN INTEGER;

 

assign  =  1  :  Die User-Gruppe group_label wird der Permission permission_label zugeordnet
assign  =  0  :  Wenn Die User-Gruppe group_label der Permission permission_label zugeordnet ist, dann wird sie aufgehoben. Ist Die User-Gruppe group_label der Permission permission_label nicht zugeordnet ist, dann wird sie zugeordnet.
assign  =  -1  :  Die Zuordnung User-Gruppe group_label / Permission permission_label wird aufgehoben

Returnwerte:
1  =  successful
0  =  no changes, because mapping is like status in assign
-1  =  permission does not exist
-2  =  group does not exist


check_permission

 
FUNCTION check_permission
(
  login IN tuse_user.use_login%TYPE,
  permission_label IN tupe_user_permission.usg_label%TYPE
)
RETURN VARCHAR2;

 

Gibt zurück, ob ein User eine bestimmte Berechtigung hat.

Returnwerte:
1  =  user has permission
0  =  user has no permission
-1  =  login not defined
-2  =  permission not defined
-3  =  login successful but password must change, please change it


get_status_message

 
FUNCTION get_status_message
(
  source IN VARCHAR2,
  status_id IN INTEGER
)
RETURN VARCHAR2;

 

Liefert für den Rückgabewert einer Funktion dieses Packages eine Klartextmeldung in englischer Sprache zurück. Hierbei entspricht source dem Funktionsnamen und status_id dem Rückgabewert dieser Funktion.
 
Download:
Next   User.sql   (Vollständiges SQL-Script zur Erzeugung des Packages)
Next   User.pdm   (Physikalisches Datenmodel für PowerDesigner 9.0)
389074 Besucher - seit dem 01.02.2005 - 1 Besucher online © 2004-2015 by Gerhard Raabe ##, ## ### #### - ##:##:##