Page 1 of 1

Authorisierung

PostPosted: Tue May 24, 2011 6:46 pm
by jsmw
Hallo,

bietet der Security-Manager eine genauere Authorisierungs-Möglichkeit (Rollen basierend) von Benutzern, wenn es um Zugriff auf Datenbank-Tabellen oder Server Actions geht. Z.B. soll ein Benutzer mit einer gewissen Rolle gewisse Daten nur lesen können aber nicht schreiben und löschen. Oder auf gewisse Server Actions zugreifen können und auf andere wieder nicht.

User-Rolle-Beziehung ist n:m.

FG
Jan

Re: Authorisierung

PostPosted: Tue May 24, 2011 9:20 pm
by rjahn
Der SecurityManager steuert den Zugriff auf die MasterSession generell und erlaubt den Zugriff auf allen darin enthaltenen Objekte/Actions. Weiters ist er zuständig für den Zugriff auf SubSessions und erlaubt den Zugriff auf alle darin enthaltenen Objekte/Actions.

Ablauf:

Jede Applikation hat zumindest eine MasterConnection (Client) und MasterSession (Server). Weiters wird pro Screen eine SubConnection (Client) und SubSession (Server) verwendet.

Der SecurityManager erlaubt oder verbietet den Login und somit die Erstellung einer MasterSession. Der SecurityManager erlaubt oder verbietet die Erstellung von SubSessions.


Der DBSecurityManager verwendet zum Auslesen der erlaubten Sessions (genauer gesagt Lifecylcle Objekte) die View V_ACCESSRULES. Wenn diese vorhanden ist, wird beim Aufbau jeder SubSession geprüft ob die Berechtigung vorhanden ist. Wenn diese View fehlt, gibt es keine Einschränkungen.

Die View sollte zumindest die Felder: USERNAME (varchar) und LIFECYCLENAME (varchar) liefern.
Der LIFECYCLENAME ist der Java Klassenname der für die Instanzierung der Session verwendet wird.

Der DBSecurityManager kann abgeleitet werden und mit einem eigenen Access Controller versehen werden oder es wird ein komplett neuer SecurityManager verwendet.


Für den Zugriff auf Objekte bzw. Actions ist der ObjectProvider zuständig. Dieser regelt die Ausführung von Methoden. An dieser Stelle kann bis auf Parameter Ebene geprüft werden. Es gibt jedoch keinen speziellen Security Mechanismus im aktuellen JVx. Es müsste der vorhandene ObjecProvider erweitert oder ein neuer implementiert werden.


Um ein Rollenkonzept abzubilden, wie es z.B. in der Applikation Packung ist, muss einerseits die DB die notwendigen Tabellen haben und die Applikation muss dynamisch aufgebaut werden, sprich die Applikation liest nach dem Login die Menüstruktur aus der DB und auch die erlaubten Rollen. Abhängig von diesen Rollen kann bereits am GUI die erste dynamische Anpassung erfolgen. Denn nicht jeder User hat die gleichen Screens oder in den Screens die gleichen Controls bzw. Rechte.
Weiters könnte man dann die Security am Server anziehen, denn ein Client ist austauschbar und die Berechtigung muss auch in der Middleware geprüft werden.

In JVx schränkt im Moment kein SecurityManager den Zugriff auf einzelne Objekte/Actions ein, es gilt die Regel, wenn ein Screen erlaubt ist, dann sind auch alle Objekte und Actions erlaubt. Es ist aber problemlos möglich ein und denselben Screen mit unterschiedlichen Lifecycle Objekten zu betreiben sofern die nötigen Objekte und Actions vorhanden sind.

Eine vollständiges User, Rollenkonzept ist in JVx im Moment nicht integriert, wurde jedoch vollständig geplant und Erweiterungen sind an jeder notwendigen Stelle möglich.

Es wäre z.B. denkbar eine spezielle RemoteApplication bzw. RemoteWorkScreenAppication zu erstellen, die sich um den Aufbau der Applikation (Menü, Toolbar, ...) kümmert.

Jede Erweiterung ist willkommen :)

Re: Authorisierung

PostPosted: Wed May 25, 2011 10:47 pm
by jsmw
Hallo Hr. Jahn,

vielen Dank für die ausführliche Erklärung.

Ich beschäftige mich in meiner Freizeit etwas mit der Anwendungsprogrammierung und traue mir aus heutiger Sich nicht zu, ein Framework, das ich gerade etwas probiere, zu erweitern.

Wenn ich es richtig verstanden haben, dann gibt es im Framework bereits einen ähnlichen Ansatz der Zugriffssteuerung über die View V_ACCESSRULES auf der User-Ebene, so dass in der View der berechtigte User für jede Klasse eingetragen werden muss. Ließe sich dieser Ansatz u.U. mit nicht so viel Aufwand auf die Rollen-Berechtigung pro Klasse erweitern bzw. umstellen?

Sie haben den Access Controller und den ObjectProvider beschrieben. Wie ist hier das Zusammenspiel zwischen den beiden Komponenten zu verstehen? Ich stelle mir den Access Controller als einen Front Controller (MVC) vor, der einmal den Login prüft und danach untersucht, ob der jeweilige Benutzer oder die jeweilige Rolle zur Ausführung einer Aktion durch den ObjectProvider berechtigt ist. Der ObjectProvider ist für mich als Handler zu verstehen. Wenn der Access Controller die Filteraufgabe übernimmt, wird dann der ObjectProvider noch für das Role-Security-Konzept benötigt?

Den Absatz über "Screen und mit unterschiedlichen Objekten" und die Berechtigung auf Screen-Ebene kann ich in der Dokumentation nicht nachvollziehen. Gibt es hierzu ein Beispiel von Ihnen?

Gibt es nähere Informationen zum geplanten User-Rollenkonzept?

FG
Jan

Re: Authorisierung

PostPosted: Thu May 26, 2011 10:15 am
by rjahn
Das aktuelle Sicherheitskonzept ist pro User. Es wird festgelegt welche Lifecycle Objekte ein Benutzer verwenden darf. Um auch noch zu definieren welche Objekte oder Actions innerhalb dieser Lifecycle Objekte aufrufbar sind muss JVx erweitert werden, da es im Moment nicht vorgesehen ist.

Der aktuelle Ansatz ruht daher, daß ein Entwickler eher ungerne konfiguriert und lieber programmiert. Daher sollten Dinge wie Berechtigungen auch simpel bleiben und am besten automatisch funktionieren. Wenn ein Entwickler jeden Zugriff konfigurieren kann/soll oder sogar müsste dann wird es schnell langweilig und unübersichtlich.
Aber wenn es sein muss, daß Zugriffe bis auf Objekte und Actions geprüft werden und der aktuelle Lifecycle-Check nicht ausreicht, dann kann der aktuelle Mechanismus nicht so ohne weiteres "umgebogen" werden, da die Aufrufe im Framework an den richtigen Stellen fehlen. Der Aufwand hängt von der Umsetzungsvariante ab und beginnt bei wenigen Stunden ist aber ohne weiteres machbar.

Wenn der aktuelle Lifecycle Check ausreicht dann kann eine einfache Lösung auch schnell umgesetzt sein, z.B.: In der Datenbank eine Tabelle für SCREENS erstellen mit Name, Klassenname und Lifecyclename. Eine Tabelle mit Roles für die gewünschten Rollen. Eine Tabelle für die Beziehung der Rollen und Screens. Eine Tabelle für die Beziehung der Rollen und User. Dann kann die V_ACCESSRULES ganz einfach aufgrund der Rollen und User Beziehung die notwendigen Lifecycle Objekte liefern.
Die Application müsste dann beim Login die Screens des aktuellen Users ermitteln um das Menü dynamisch anzupassen um nicht immer alle Screens anzuzeigen. Weiters könnten die Rollen des Users ausgelesen werden um in der Applikation zur Verfügung zu stehen.

Der beschriebene Ansatz wurde in JVx bereits vorgesehen und ist im Interface
com.sibvisions.javax.rad.IWorkScreenApplication bereits definiert:

Code: Select all
public boolean hasRole(String pRoleName);

Für die Umsetzung braucht es allerdings eine neue Application Implementierung, da die aktuelle Application die Screens nicht dynamisch lädt bzw. öffnet.

Die Klassen SecurityManager, AccessController und ObjectProvider sind reine Server Objekte und haben keine UI Verbindung.

Der SecurityManager übernimmt die Authentifizierung des Clients bzw. einer MasterConnection. Die Authentifizierung kann z.B gegen die DB geprüft werden oder LDAP oder mit OAuth usw.

Der SecurityManager liefert einen AccessController mit dem in einer Session geprüft wird ob das definierte Lifecycle Objekt verwendet werden darf.

Der ObjectProvider wird von der Session aufgerufen wenn ein Objekt bzw. eine Action aufgerufen werden soll. Im Prinzip ist der ObjectProvider ein Container für Lifecycle Objekte und steuert den Zugriff auf diese Objekte.
Um auf Objekt/Action Zugriff zu prüfen, könnte der ObjectProvider den AccessController des SecurityManagers verwenden bevor ein Aufruf erfolgt.


Der Ansatz "Screen mit unterschiedlichen Objekten" war so gemeint:

Am Client wird eine SubConnection pro Screen geöffnet. Jeder SubConnection wird ein Lifecycle Name gesetzt. Es spricht aber nichts dagegen den selben Screen mit unterschiedlichen SubConnections zu öffnen, sprich gleiche Client Klasse, unterschiedliche Server Klassen.


Da sie im Moment eher an einer schnellen Lösung interessiert sind, könnte ich noch folgenden Vorschlag anbieten:

Die Lifecycle Objekte haben pro Objekt und Action eine Java Methode. Sie können in Lifecycle Objekten jederzeit auf Session Informationen via SessionContext zugreifen. Jede Session hat Properties die mit dem Client synchronisiert werden.
Nun wäre es möglich das sie beim Zugriff auf ein Objekt/Action selbst prüfen ob die Berechtigung passt z.B.:

Code: Select all
//declared in SubSession-Lifecycle Object
public ResourceAccess getResourceAccess()
{
   checkAccess("resourceAccess");
   
   ResourceAccess rsa = (ResourceAccess)get("resourceAccess");
   
   if (rsa == null)
   {
      rsa = new ResourceAccess();
      
      put("resourceAccess", rsa);
   }
   
   return rsa;
}

//declared in MasterSession-Lifecycle Object
protected void checkAccess(String pProperty)
{
   if (SessionContext.getCurrentSession().getProperty(
                                    IConnectionConstants.PREFIX_SERVER + 
                                    IConnectionConstants.PREFIX_SESSION +
                                    "role_admin") != null)
   {
      throw new SecurityException("Access denied!");
   }
}

Um diese Lösung Wasserdicht zu machen müssten reine Server Properties eingesetzt werden, da diese dann nicht zum Client übertragen werden, sprich ein nicht serialisierbares Objekt verwenden um die Rollen zu speichern, z.B.:

Code: Select all
public DBAccess getDBAccess() throws Exception
{
   DBAccess dba = (DBAccess)get("dBAccess");
   
   if (dba == null)
   {
      IConfiguration config = SessionContext.getCurrentSessionConfig();
      
      dba = DBAccess.getDBAccess(DBSecurityManager.getCredentials(config));
      dba.open();
      
      put("dBAccess", dba);

      //read roles from database
      UserRoles roles = new UserRoles();
      roles....
      
      SessionContext.getCurrentSession().setProperty("user-roles", roles);
   }
   
   return dba;
}

protected void checkAccess(String pProperty)
{
   UserRoles roles = (UserRoles)SessionContext.getCurrentSession().getProperty("user-roles");

   if (!roles.isAdmin())
   {
      throw new SecurityException("Access denied!");
   }
}


Etwas Generischer:

Wenn Sie als Basis Klasse für Ihre Lifecycle Objekte ein GenericBean einsetzen, könnten sie von diesem ableiten und die Methoden

Code: Select all
public Object get(String pName)
public Object invoke(String pMethod, Object... pParams)

überschreiben. Diese Methoden werden verwendet um auf Objekte/Actions zuzugreifen und natürlich können sie auch dort die Security prüfen.


Sie sehen, es gibt viele Lösungen, doch es muss noch einfacher und allgemeiner werden für die Entwickler. Daher wird es auch eine Integration in JVx geben, doch diese ist noch nicht fixiert. Die Lösung wird aber ähnlich den oben beschriebenen sein.

Im Moment ist die Dokumentation zwar sehr vernünftig, doch besser geht immer und es würden die ein oder anderen Themen schon noch hilfreich sein. Da JVx aber kein kommerzielles Framework ist, dauern gewisse Dokus leider etwas länger als andere :)

Re: Authorisierung

PostPosted: Thu May 26, 2011 8:16 pm
by jsmw
Danke für die Überlegungen und Darstellungen! Werde mich nun einmal damit beschäftigen.