MySQL Rechtesystem

Gsus

schwankend^^
ID: 215354
L
22 Mai 2006
1.553
68
Hallo,

mal wieder stehe ich vor einem kleinen Problem. Ich möchte gerne ein Rechtesystem entwickeln, wobei der User mehrere Möglichkeiten hat an ein gewisses Recht zu kommen:
  1. Ein User ist Mitglied einer Usergruppe, welche bestimmte Standard-Rechte hat
  2. Ein User hat ein spezielles Recht, oder ihm fehlt ein spezielles Recht

Die aktuelle Tabellenstruktur sieht dafür momentan so aus:
{colsp=3} rechte
rechteid|name|...

{colsp=3} user
userid|name|...

{colsp=3} user_rechte
userid|rechteid|wert (0,1)

{colsp=3} usergruppen
gruppenid|name|...

{colsp=2} usergruppen_user
gruppenid|userid

{colsp=2} usergruppen_rechte
gruppenid|rechteid

Nun möchte ich zu einem bestimmten User alle Rechte auslesen die er hat (also entweder durch eine Benutzergruppe oder durch einen Eintrag mit wert = 1 in der user_rechte tabelle), ohne dass die die ihm aberkannt wurden (durch einen Eintrag mit wert = 0 in der user_rechte tabelle) mitgezählt werden.

Mein Ansatz war nun, erst mit einer Abfrage alle Rechte zu selektieren die er über eine Benutzergruppe hat und diese mittels eines UNION zusammenzuführen mit allen die ihm speziell anerkannt wurden. Dies würde dann also folgendermaßen aussehen:

Code:
SELECT *
    FROM rechte
    LEFT JOIN usergruppen_rechte USING (rechteid)
    LEFT JOIN usergruppen_user USING (gruppenid)
    WHERE userid = 1
UNION
SELECT *
    FROM rechte
    LEFT JOIN user_rechte USING (rechteid)
    WHERE userid = 1
        AND wert = 1

Nun sind aber auch die Rechte noch im Result enthalten, welche dem User durch einen Eintrag mit wert = 0 in user_rechte aberkannt wurden.
Ausserdem finde ich diese UNION-Konstruktion nicht besonders schön, stehe aber zur Zeit ziehmlich auf dem Schlauch, wie ich das am besten anpacken kann und wäre daher für jede Hilfe dankbar.

Vielen Dank im vorraus für eure Hilfe,

mfg
Gsus
 
Also das User-Recht wiegt mehr als das Gruppen-Recht richtig?
Und im User Recht stehen nur eventuell ein Eintrag wenn er doch etwas darf bzw. nicht. Also quasi der Unterschied?

Dann müsstest du beim ersten Select noch einen Join zu den Userrechten machen und nur die holen, die nicht auch dort vorhanden sind. Quasi die entfernen die in den Userrechten drin sind.

Also beim Join auf null prüfen.
 
Also das User-Recht wiegt mehr als das Gruppen-Recht richtig?
Und im User Recht stehen nur eventuell ein Eintrag wenn er doch etwas darf bzw. nicht. Also quasi der Unterschied?

Das ist soweit richtig ja. Danke schonmal für deine Antwort, darauf hätte ich nun auch echt selber kommen können :) Die Lösung ist nun also:

Code:
SELECT *
    FROM rechte AS r
    LEFT JOIN usergruppen_rechte USING (rechteid)
    LEFT JOIN usergruppen_user USING (gruppenid)
    WHERE userid = 1
        AND NOT EXISTS (SELECT *
                                 FROM user_rechte
                                 WHERE rechteid = r.rechteid
                                     AND userid = 1
                                     AND wert = 0)
UNION
SELECT *
    FROM rechte
    LEFT JOIN user_rechte USING (rechteid)
    WHERE userid = 1
        AND wert = 1

Das funktioniert zwar schon, jedoch finde ich diese Abfrage ehrlichgesagt nicht wirklich schön :D gibt es hier vielleicht noch eine bessere Möglichkeit für? Kann man das ganze zum Beispiel auch irgenwie in einer Query lösen?

mfg
Gsus
 
  1. Nur Rechte definieren die man hat, jedoch keine die man nicht hat
  2. Gruppen und Personen in einem hierarchischen Modell speichern (Nested Sets)
  3. wenn noch speziellen Nutzern bestimmte Rechte zugewiesen werden sollen: über eine 1:n-Relation lösen

Dann findet man die Rechte eines Nutzers in einer Gruppe durch einen extrem einfachen Query (Da "Vererbung" durch NestedSets genutzt wird) und die zusätzlichen Rechte für einen speziellen Nutzer werden per LEFT JOIN gefunden.
 
  1. Nur Rechte definieren die man hat, jedoch keine die man nicht hat
Kann man auch, aber was wenn man eine Blacklist nun mal haben will?

Wenn User XY auf keinen Fall das Recht z haben darf, dann kannst du das so ja ausschließen, dann passiert auch nichts, wenn man seine Gruppenzugehörigkeit ändert.

Kann schon seine Vorteile haben oder!?
 
[/LIST]Kann schon seine Vorteile haben oder!?

Macht das Modell aber viel komplexer, wie du siehst. Auch keines der traditionellen ACL-Systeme (RBAC, MAC, Bell-LaPadula) definiert Ausschluss-Rechte.
Zumal es einfach ein Verstoß der Gruppen-Definition ist, wenn ich mich in einer Gruppe befinde, die das Recht x hat aber ich dieses nicht habe, dann kann ich streng genommen auch nicht in der Gruppe sein, sondern müsste in einer anderen Gruppe sein.
 
Naja in der Realität gibt es sowas aber. Geschäftsführer die bestimmtes nicht dürfen, was andere Geschäftsführer dürfen...

Habe ja nie gesagt das es normal ist. Aber wenn sowas gewollt wird, wieso nicht?
Nur weil es komplizierter ist?
 
sowas sollte doch auch funktionieren:

Code:
SELECT benötigte-werte
FROM rechte 
WHERE rechteid IN 
   ( SELECT rechteid FROM user_rechte WHERE wert = 1 AND userid = ?user )
OR rechteid NOT IN 
   ( SELECT rechteid FROM user_rechte WHERE wert = 0 AND userid = ?user )
AND rechteid IN  
   ( SELECT rechteid FROM usergruppen_rechte INNER JOIN usergruppen_user USING (gruppenid) WHERE  userid = ?user )
 
Naja in der Realität gibt es sowas aber. Geschäftsführer die bestimmtes nicht dürfen, was andere Geschäftsführer dürfen...
Aber das ist doch der typische Fall, dass das Gruppensystem dann falsch modelliert wurde. Denn Geschäftsführer sind erst mal alle gleich, also darf keiner über andere Geschäftsführer bestimmen, nur manche bekommen eben zusätzlich dieses Recht eingeräumt.
 
Ja nee, es wird halt festgehalten, was einer halt nicht darf, was normalerweise ein Geschäftsführer darf.
Du weißt was Prokura ist? Du weißt was er alles darf? Es gibt Ausnahmen wo er halt dann etwas nciht darf (Wobei das nur Firmenintern dann gilt und nicht nach ausenhin).
 
Wie die Rechte in echt sind, ist doch egal, es geht doch nur darum diese sinnvoll zu modellieren. Es hat schon seine Gründe warum traditionelle ACL-Systeme nur die Rechteerlaubnis und nicht Rechteverbot kennen.