Rechteverwaltung
MichoLee
- programmiertechnik
0 Deus Figendi0 MichoLee0 Beat0 michilee
0 Frank (no reg)0 michilee
0 Deus Figendi (noReg)
Hallo Leute,
ich sollte in java eine kleine Rechteverwaltung realisieren. Es gibt mehrere User (man könne auch verschiedenen Gruppen zugeordnet sein)
Jeder User kann nun Todo's Titel (Aufgaben) erstellen. Jede Toto hat dann Subtodos. Sprich, einzelne Subtodos, um die Aufgabe zu realisieren.
Die Rechteverwaltung sollte nun so aussehen, dass jeder User ein Todo Title und dazugehörige Subtodos anlegen kann, die dann nur er selber sieht.
Die Rechteverwaltung sollte es nun erlauben, dass ein User, auch für andere Leute aus der eigenen Gruppe oder bestimmten anderen Gruppen oder bestimmten Usern oder gleich der ganzen Allgemeinheit sichtbar anlegen kann. Der User sollte auch die Möglichkeit haben, dass er bestimmten Gruppen/Usern/Allgemeinheit die Erlaubnis geben kann, das Todo, bzw. einzelne Subtodos du editieren oder im todo neue Subtodos anlegen zu dürfen.
Meine Frage nun. Würde es Sinn machen, die Rechteverwaltung nach dem Schema ähnlich wie 777, 760 wie in Lnux zu gestalten? Der User müsste dann dann beim Anlegen des Todo's oder Subtodos immer die Rechte definieren. Schwierig wird es aber, wenn er zusätzlich zu den 700 nur bestimmte User freischalten will, für sehen, oder sehen+bearbeiten. Es sollte alles natürlich nicht zu komplex werden aber dennoch flexibel beim Anlegen.
Hättet Ihr irgendwelche Bedenken an meinem Vorhaben?
Grüße
Michaelaas
Ich vermute mal, dass du irgendein DBMS im Hintergrund hast, mit dem du arbeitest.
Üblich bei solchen Konstellationen sind dann Kreuztabellen (heißen die so?).
Du hast ja wahrscheinlich dann ohnehin zwei Tabellen, Benutzer und Listen.
User:
uid | name | gruppe
0 | root | administratoren
1 | user1 |
2 | user 2 | priviligierte_benutzer
3 | us3r | foobar
Wenn dem so ist ist das schonmal schlecht ^^ Trenne die Gruppen von den Benutzern:
Groups:
gid | name
0 | Administratoren
1 | priviligierte Benutzer
2 | foobar
und erstelle eine Kreuztabelle:
ugid | uid | gid
0 | 0 | 0
1 | 2 | 1
2 | 3 | 2
User0 ist also Gruppe0 zugeordnet, User2 der Gruppe1 und User3 der Gruppe2. Das ermöglicht es auch in mehreren Gruppen zu sein..
ugid | uid | gid
3 | 2 | 2
schon ist Benutzer2 in Gruppe1 und in Gruppe2 :)
Und mit deinen 2do-Listen machst du das gleiche:
Lists:
lid | name | subof | besitzer
0 | liste1 | null | 0
1 | liste2 | null | 1
2 | liste2.2 | 1 | 1
3 | liste3 | null | 2
Liste1 gehört nun root und ist seine "Überliste". Liste2 gehört user1 und ist seine Überliste, sie enthält Liste2.2, die auch user1 gehört.
Und dann kreuzt du auch das:
ListRights
lrid | uid | gid | lid | rechte
0 | 0 | null | 0 | 5
1 | 1 | null | 1 | 5
2 | 1 | null | 2 | 5
3 | 2 | null | 3 | 5
Ich habe "6" jetzt mal als höchsten Wert für maximale Rechte mir ausgedacht:
0 - keine Rechte
1 - Lesen
2 - schreiben
3 - überschreiben / löschen
4 - ausführen
5 - überschreiben, löschen und ausführen
Unter bestimmten Voraussetzungen kann man auch wollen, dass Benutzer nur schreiben und nicht lesen können sollen. Keine Ahnung, was dein Projekt da vor sieht.
Jedenfalls würde die Tabelle oben jetzt jedem Benutzer maximal alle Rechte an seinen eigenen Listen gewähren. Jetzt legt root eine neue Liste an und will priviligierte_benutzer sowie us3r erlauben darauf lesend und schreibend zuzugreifen:
Lists:
lid | name | subof | besitzer
4 | liste1.3 | 0 | 0
ListRights
lrid | uid | gid | lid | rechte
4 | null| 1 | 4 | 2
5 | 3 | null | 4 | 2
Du kannst Gruppen- und Benutzer-Berechtigungen auch in getrennten Tabellen speichern oder in der gleichen Spalte und natürlich kannst du auch ein feineres oder gröberes Rechtesystem erstellen.
Um jetzt noch allgemeine Regeln wie "für alle" oder so zu bauen verfrachtest du einfach _alle_ Benutzer in eine Gruppe namens "Benutzer" oder "Gäste" oder was weiß ich und trägst z.B. ein...
Groups:
gid | name
3 | alle
User/Group-Kreuztabelle
ugid | uid | gid
3 | 0 | 3
4 | 1 | 3
5 | 2 | 3
6 | 3 | 3
ListRights
lrid | uid | gid | lid | rechte
5 | null| 3 | 4 | 1
Nun sind alle User in Gruppe "alle" und die Gruppe "alle" hat lesenden Zugriff auf Liste4 (namens Liste1.1).
Hey,
boah, du hast mir ja die ganze Lösung ganz detailliert niedergeschrieben. Echt vielen Dank.
Ich vermute mal, dass du irgendein DBMS im Hintergrund hast, mit dem du arbeitest.
Üblich bei solchen Konstellationen sind dann Kreuztabellen (heißen die so?).
Wir haben diese in der Schule immer als "Zwischentabellen" bezeichnet :-)
Deine Lösung ist natürlich sehr gut. Wichtig bei der Programmierung naher ist zu beachten, falls eine liste.5 einer Gruppe und zusätzlichen bestimmtne Personen etwas erlaubt, dass es nicht zu überschneidungen kommt:
Bsp. us3r ist in gruppe foobar. Die liste.5 berechtigt nun die Gruppe zum lesen und schreiben, aber us3r nur zum lesen. Da müsste ich mir dann ein ehierarchie überlegen, was entweder überwiegt oder man einfach sinnvollerweise dann immer die höchsten, bzw. besten Rechte nimmt.
Vielen Dank nochmals. Ich spiele deinen Ansatz mal mit ein paar Beispielen durch. Übersichtlich sieht es aus. Ich versuche mich auch hineinzusteigern, wie die administration in Zukunft aussehen könnte, bei vielen Benutzern. (Ich kenne es vom meinem Praktikum, dass oft ein Chaos bei der Rechteverwaltung herscht. Eine Person ist in vielen Gruppen vertreten, die Gruppen haben wiederum bestimmte Rechte. Es kam dann oft vor, dass bestimmte Gruppen untereinander ähnliche Rechte hatten aber doch an manchen Punkten verschieden, so dass der Chaos vorprogrammiert ist, wenn man 1000-2000 User verwaltet :-)
Grüße
Bsp. us3r ist in gruppe foobar. Die liste.5 berechtigt nun die Gruppe zum lesen und schreiben, aber us3r nur zum lesen. Da müsste ich mir dann ein ehierarchie überlegen, was entweder überwiegt oder man einfach sinnvollerweise dann immer die höchsten, bzw. besten Rechte nimmt.
Wenn du jemandem deinen Hausschlüssel leihst, und dieser bei dieser Gelegenheit dann die Schlösser auswechseln lässt, hast du ein Problem.
mfg Beat
Hi
Bsp. us3r ist in gruppe foobar. Die liste.5 berechtigt nun die Gruppe zum lesen und schreiben, aber us3r nur zum lesen. Da müsste ich mir dann ein ehierarchie überlegen, was entweder überwiegt oder man einfach sinnvollerweise dann immer die höchsten, bzw. besten Rechte nimmt.
Wenn du jemandem deinen Hausschlüssel leihst, und dieser bei dieser Gelegenheit dann die Schlösser auswechseln lässt, hast du ein Problem.
da hast du natürlich recht. ich überlege mir, sobald man schreibe, bzw. editierrechte auf eine datei, bzw. todo hat, ob er auch wirklich nur den inhalt ändern kann/darf oder auch die rechte der datei/todo anpassen darf, falls er zum beispiel in der gruppe drin ist oder eine einzelberechtigung erhält. (wo das sinn oder unsinn macht, muss ich mir natürlich noch überlegen)
grüße
Hallo, geht es darum ein Rechtesystem zu haben und zu benutzen? oder darum eines zu bauen (zu Lernzwecken)?
Wie wär's mit einem ACL Modell
ACL = Access Control List
Solch ein ACL besteht aus "Nodes" bzw. Einträgen, welche folgende Entitäten miteinander verbinden:
(In Datenbankprosa also: ca. 1 Tabelle mit ca. 4 Spalten)
Ist eigentlich ein skalierbares generisches Konzept. Denn als Benutzergruppe käme auch in Frage: Ersteller/Eigentümer und "alle anderen". Man könnte klein Anfangen und nach und nach ausbauen.
d.h. beim Anlegen eines Todos/Totos müsste dann auch ein (oder mehr?) Eintrag/Einträge in solch eine handgestrickte ACL Tabelle gemacht werden.
Vererbungsmechanismen würde ich mal ausser Acht lassen.
Ein Benutzer müsste dann auf alle "Gruppen" gemappt werden, wo er Mitglied ist (das geht mit einfachen Joins und Union), zusätzlich (für den Fall dass er einzelberechtigt sein könnte) muss er selbst noch als "pseudo-Gruppe" auftreten.
Mit einer Abfage nach Benutzer, bzw Liste der Gruppen und natürlich dem Objekt und ggf Betriebsart (auch alles wieder nur JOIN) könntest du in Erfahrung bringen ob DENY oder ALLOW oder gar nix.
Wie du den Fall von nicht vorhandenen Rechten oder wiedersprüchlichen Rechten handhabst, ist dein Bier.
Ciao, Frank
Hi Frank,
Hallo, geht es darum ein Rechtesystem zu haben und zu benutzen? oder darum eines zu bauen (zu Lernzwecken)?
natürlich hauptsächlich um lernzwecke, später würde ich mich auch heranwagen und versuchen dies im kleinen umzusetzen. deshalb wäre es ja wichtig, dass man eine gute grundlage hat, die später auch problemlos erweiterbar und vor allem flexibel ist. Ich finde aber die Lösung von "Deus Figendi" sehr gut.
Wie wär's mit einem ACL Modell
ACL = Access Control List
Solch ein ACL besteht aus "Nodes" bzw. Einträgen, welche folgende Entitäten miteinander verbinden:
- das Objekt, das beschützt werden soll (dein Toto/Todo - was auch immer das sein soll)
- eine Referenz zu einer Benutzergruppe (Achtung: die können theoretisch auch verschachtelt werden)
- eine Betriebsart bzw Benutzungsart, z.b. "Lesen" oder "Ändern"
- ein Flag ALLOW oder DENY (wobei DENY immer Vorrang haben sollte)
(In Datenbankprosa also: ca. 1 Tabelle mit ca. 4 Spalten)
Ich habe in mein Script geschaut. Es gibt ACL und Capability List. Capability List speichert zu jedem Benutzer die Datei und seine Rechte dazu. Ich speichere, wie du bereits erwähnst hast, das ganze etewa wie folgt:
Datei User/Gruppe Betriebsart Flag
liste_1 us3r w,r Für was man diesen Flag brauchen würde, weiß ich leider nicht
user_2 r -
foobar r -
Ist eigentlich ein skalierbares generisches Konzept. Denn als Benutzergruppe käme auch in Frage: Ersteller/Eigentümer und "alle anderen". Man könnte klein Anfangen und nach und nach ausbauen.
Der Eigentümer ist natürlich auch wichtig. Wenn man die Benutzergruppen verschachtelt, bzw. untereinander auch vererbt, dann denke ich, dass es schnell unübersichtlich wird. (Der administrative Aufwand später im Betrieb)
Bei den Todos überlege ich mir auch, ob ich es möglich machen soll, dass der Eigentümer, das Eigentüm übertragen kann oder jemand von der Gruppe, die Gruppenrechte ändern? (das wäre wiederum zu speziell, was die software, bzw. die Todos machen sollten/könnten)
Ein Benutzer müsste dann auf alle "Gruppen" gemappt werden, wo er Mitglied ist (das geht mit einfachen Joins und Union), zusätzlich (für den Fall dass er einzelberechtigt sein könnte) muss er selbst noch als "pseudo-Gruppe" auftreten.
Das muss ich noch etwas mehr in mich wirken lassen
Mit einer Abfage nach Benutzer, bzw Liste der Gruppen und natürlich dem Objekt und ggf Betriebsart (auch alles wieder nur JOIN) könntest du in Erfahrung bringen ob DENY oder ALLOW oder gar nix.
Das DENY und ALLOW habe ich weiterhin nicht ganz verstanden. Durch die Betriebsart r oder w sage ich ja bereits, ob, bzw. was der Benutzer oder die Benutzergruppe machen darf. Wenn er nicht darf, taucht er eh nicht in der Liste zur Datei/Todo auf.
Wie du den Fall von nicht vorhandenen Rechten oder wiedersprüchlichen Rechten handhabst, ist dein Bier.
Genau :-) Danke nochmals für die guten Tipps
Hi,
zum Thema "Flag" ...
Es ist eine Frage der Sichtweise. Du willst ja in einer Spalte die Betriebsarten als komma-separierte Liste speichern (r,w oder r). Damit reduzierst du zwar die Menge der gesamt gespeicherten Records aber du müsstes jeden einzelnen auswerten um zu sehen ob r, w oder beides gesetzt ist.
Solch ein boolsches Flag (für Deny/Allow) kannst du auch implizit haben indem du halt nur die erlaubten Benutzungsmodi speicherst, also nur r wenn schreiben nicht erlaubt sein soll.
Lässt du die Benutzungsmodi atomar, also 1 Record pro Datei, Benutzer(Gruppe), "Recht". Kannst du wunderbar indizieren auf das "Recht", d.h. wenn ein "Lese-Recht" abgefragt wird brauchst du nicht alle Datensätze lesen, sondern nur die mit "Recht" = "Lesen", ebenso bei "Schreiben".
Schreiben beinhaltet warhscehinlich bei dir "Anlegen", "Löschen" und "Ändern".
Das könnte ab einer gewissen Menge Datensätze schon einen Unterschied machen.
zum Thema "Benutzer und Gruppen"
Wenn ein Benutzer in mehreren (u.U. auch verschachtelten) Gruppen enthalten sein kann, solltest du diese Komplexität auflösen indem du eine Liste erstellst, in welcher der Benutzer mit allen seinen Gruppen aufgeführt ist.
Wenn der Benutzer auch einzeln Rechte erhalten kann, dann muss er in der Implementierung auch wie eine Gruppe behandelt werden können. Stell dir deine Zuordnungstabelle aus Benutzer/Gruppe, Rechten und Datei vor. Benutzer/Gruppe ist ein Name (denormalisiert) oder eine Id (normalisiert), aber du kannst für ein Feld in einer Tabelle keinen Fremdschlüssel auf 2 andere Tabellen haben. Also musst du entweder ohne Fremdschlüssel arbeiten, oder Benutzer und Gruppe stellen für die Überprüfung von Rechten genau dieselbe Rollen (sind also vom gleichen Entitätstyp) => sind also in derselben Tabelle abgelegt.
Aber der beste Rat ist: Probieren geht über Studieren. Probier eine oder mehrere Varianten aus, analysiere Vorteile, Nachteile, Aufwand. Evt. wirst du bei der einen oder anderen Variante irgendwo in eine Sackgasse geraten. Dann hast du dennoch etwas gelernt. ;-)
Cheers, Frank
Hi,
zum Thema "Flag" ...
Es ist eine Frage der Sichtweise. Du willst ja in einer Spalte die Betriebsarten als komma-separierte Liste speichern (r,w oder r). Damit reduzierst du zwar die Menge der gesamt gespeicherten Records aber du müsstes jeden einzelnen auswerten um zu sehen ob r, w oder beides gesetzt ist.
Genau. Ich könnte eigentlich mehrere Records für jedes einzelne r, w und x schreiben. (Fall ich das später feiner granulieren würde, also mehrs als die drei r, w,x, würde das ganze etwa durcheinander kommen)
Wenn ich alles in ein Record mache, könnte ich wie du bereits erwähnt hast komma-separiert alles in eine Spalte schreiben. Entweder, nur die erlaubten dort aufzählen, "r,w", "r" oder, wenn ich das mit Deny richtig verstanden habe, dann alle Buchstaben aufzählen "r,w,x" und in der Flag Tabelle, dann "1,1,0) oder Bitweise/Stellenweise aufsummieren (4,2,1)
Das hat aber einen Nachteil, wenn (aus welchem Grund auch immer) ein neuer Benutzungsmodi hinzukommen würde.
Solch ein boolsches Flag (für Deny/Allow) kannst du auch implizit haben indem du halt nur die erlaubten Benutzungsmodi speicherst, also nur r wenn schreiben nicht erlaubt sein soll.
siehe oben.
zum Thema "Benutzer und Gruppen"
Wenn ein Benutzer in mehreren (u.U. auch verschachtelten) Gruppen enthalten sein kann, solltest du diese Komplexität auflösen indem du eine Liste erstellst, in welcher der Benutzer mit allen seinen Gruppen aufgeführt ist.
Genau
Wenn der Benutzer auch einzeln Rechte erhalten kann, dann muss er in der Implementierung auch wie eine Gruppe behandelt werden können. Stell dir deine Zuordnungstabelle aus Benutzer/Gruppe, Rechten und Datei vor. Benutzer/Gruppe ist ein Name (denormalisiert) oder eine Id (normalisiert), aber du kannst für ein Feld in einer Tabelle keinen Fremdschlüssel auf 2 andere Tabellen haben. Also musst du entweder ohne Fremdschlüssel arbeiten, oder Benutzer und Gruppe stellen für die Überprüfung von Rechten genau dieselbe Rollen (sind also vom gleichen Entitätstyp) => sind also in derselben Tabelle abgelegt.
Genau, in einem Feld kann ein Fremdschlüssel nicht auf zwei andere Tabelle verweisen. Außer, man würde noch eine Spalte anlegen, an welche Tabelle das gemappt wird. Das macht aber wenig Sinn, dann könnte ich gleich zwei Spalten machen, einmal für Benutzer und einmal für Gruppen. Deshalb ist die Idee, dass ein einzelner Benutzer, bzw. ich/er selber eine Gruppe bin.
Aber der beste Rat ist: Probieren geht über Studieren. Probier eine oder mehrere Varianten aus, analysiere Vorteile, Nachteile, Aufwand. Evt. wirst du bei der einen oder anderen Variante irgendwo in eine Sackgasse geraten. Dann hast du dennoch etwas gelernt. ;-)
»
Dankeschön übrigens für alle die Tipps und Infos. Ich versuche viel zu lernen und zu probieren :-)
Grüße
Deine Lösung ist natürlich sehr gut. Wichtig bei der Programmierung naher ist zu beachten, falls eine liste.5 einer Gruppe und zusätzlichen bestimmtne Personen etwas erlaubt, dass es nicht zu überschneidungen kommt:
Bsp. us3r ist in gruppe foobar. Die liste.5 berechtigt nun die Gruppe zum lesen und schreiben, aber us3r nur zum lesen. Da müsste ich mir dann ein ehierarchie überlegen, was entweder überwiegt oder man einfach sinnvollerweise dann immer die höchsten, bzw. besten Rechte nimmt.
Meiner Auffassung nach gelten einfach alle Rechte, in dem Sinne also nicht das höchste ^^
In dem Beispiel hieße das us3r darf lesen, lesen und schreiben. Drei Rechte auf einmal.
Diese Ansicht stammt von komplexeren Softwaren, die einfach viel mehr unterschiedliche Rechte gewähren können. Ich administriere z.B. ein SimpleMashines-Forum. Und in Foren- (oder im selfRaum sollte ich vielleicht "Board" sagen ^^) also in Boardsoftware gibt es ja eine ganze Menge verschiedenster Rechte, darf jemand lesen, schreiben, neue Themen erstellen, Umfragen erstellen, eigene Beiträge editieren, fremde Beiträge editieren, löschen, verschieben, vereinen, teilen, die Mitgliederliste betrachten, die Profile betrachten, bestimmte Daten innerhalb derer betrachten und so fort...
Will sagen es gibt einfach eine ganze Menge höchst verschiedener Rechte.
Nun bekommt ein Moderator z.B. alle Rechte Beiträge zu manipulieren, aber er bekommt nicht das Recht Umfragen zu erstellen. Dafür gibt es eine zweite Gruppe der "Interviewer", diese erhalten das Recht Umfragen zu erstellen, sowie Themen zu erstellen, in denen nur einzelne Benutzer antworten können/dürfen.
Der Interviewer erhält aber nicht die Rechte Beiträge zu manipulieren (verschieben, editieren, teilen, vereinen etc.). Wenn jetzt jemand Moderator und Interviewer ist, dann verliert er aufgrund dessen dass er gerade seiner Interviewer-Tätigkeit nachgeht keinesfalls das Recht auch Beiträge zu manipulieren.
Also dieses untersagen würde ich einfach weg lassen, wenn Benutzer der Meinung sind bestimmte Benutzer auszuschließen, die aber einer Gruppe angehören, die man einschließen will, dann muss man die Benutzer der Gruppe eben einzeln zulassen oder eine neue Gruppe gründen, die eben die "unerwünschten" Benutzer exkludiert.
Bei dem ganzen Geschwafel ist mir auch noch was eingefallen. Oben habe ich dargestellt man könne diese Rechte so wunderbar vereinen als "Schreiben und ausführen" oder so.
Tatsächlich ist es vielleicht aber sinnvoller weil skalierbarer die Rechte einzeln zu vergeben. Also Lesen ist ein Recht, schreiben ist ein Recht, Überschreiben ist ein Recht, Löschen ist ein Recht und Ausführen auch.
Wenn man jemandem alles erlauben will kann man ja durchaus fünf Zeilen in der Tabelle spendieren.
Der Grund: Man will vielleicht, dass jemand überschreiben darf aber nicht schreiben, weil er nichts neues anlegen soll, sondern nur vorhandenes ändern darf. Oder man möchte das genaue Gegenteil, so PM-mäßig, jeder kann mir was auf die Liste schreiben, aber niemand außer mir kann sie lesen.
Und natürlich er fast übliche Fall: Lesen und Schreiben erlaubt man bestimmten Personen, aber um Vandalismus vorzubeugen untersagt man editieren und löschen. Die Personen/Gruppen können also nur neue Punkte in deiner Liste anlegen, aber keine vorhandenen ändern.
Unmöglich dürfte es allerdings sein, Löschen oder Überschreiben zu erlauben, das Lesen aber nicht ^^ explizit unterbinden würde ich diese Kombination aber auch nicht. Wenn das jemand so erlaubt kann man halt durch gezielte Manipulation von Formular-Inhalten o.ä. durchaus was löschen oder überschrieiben, was man gar nicht sehen kann, aber das wurde dann ja irgendwo auch so eingestellt, also was solls.
Hey Deus,
vielen Dank, du hast die wichtigsten Betriebsarten eigentlich schon aufgezählt und soagr gleich erläutert.
Mit überschreiben und editieren meinst du aber zweimal das gleiche ne?
Grüße
Mit überschreiben und editieren meinst du aber zweimal das gleiche ne?
jep