Frage

Ich stoße oft auf das folgende Szenario, in dem ich viele verschiedene Arten von Berechtigungen anbieten muss.Ich verwende hauptsächlich ASP.NET / VB.NET mit SQL Server 2000.

Szenario

Ich möchte ein dynamisches Berechtigungssystem anbieten, das mit verschiedenen Parametern arbeiten kann.Nehmen wir an, ich möchte entweder einer Abteilung oder nur einer bestimmten Person Zugriff auf eine Anwendung gewähren.Und stellen Sie sich vor, wir hätten eine Reihe von Anwendungen, die ständig wachsen.

In der Vergangenheit habe ich eine der beiden folgenden Möglichkeiten gewählt, die ich kenne, um dies zu tun.

  1. Verwenden Sie eine einzelne Berechtigungstabelle mit speziellen Spalten, die zur Bestimmung eines Antrags der Parameter verwendet werden.Die speziellen Spalten in diesem Beispiel sind Typid und Typeauxid.Der SQL würde ungefähr so ​​aussehen.

    SELECT COUNT(PermissionID)
    FROM application_permissions
    WHERE
    (TypeID = 1 AND TypeAuxID = @UserID) OR
    (TypeID = 2 AND TypeAuxID = @DepartmentID)
    AND ApplicationID = 1
    
  2. Verwenden Sie für jede Art von Erlaubnis eine Mapping -Tabelle und verbinden Sie sie dann alle zusammen.

    SELECT COUNT(perm.PermissionID)
    FROM application_permissions perm
    LEFT JOIN application_UserPermissions emp
    ON perm.ApplicationID = emp.ApplicationID
    LEFT JOIN application_DepartmentPermissions dept
    ON perm.ApplicationID = dept.ApplicationID
    WHERE q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    

Meine Gedanken

Ich hoffe, dass die Beispiele Sinn ergeben.Ich habe sie zusammengeschustert.

Das erste Beispiel erfordert weniger Arbeit, aber keines davon scheint die beste Antwort zu sein.Gibt es einen besseren Weg, damit umzugehen?

War es hilfreich?

Lösung

Ich stimme John Downey zu.

Persönlich verwende ich manchmal eine gekennzeichnete Aufzählung von Berechtigungen.Auf diese Weise können Sie bitweise AND-, OR-, NOT- und XOR-Operationen für die Elemente der Aufzählung verwenden.

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

Anschließend können Sie mehrere Berechtigungen mit dem bitweisen AND-Operator kombinieren.

Wenn ein Benutzer beispielsweise Benutzer anzeigen und bearbeiten kann, ist das binäre Ergebnis der Operation 0000 0011, was in eine Dezimalzahl umgewandelt 3 ist.
Anschließend können Sie die Berechtigung eines Benutzers in einer einzelnen Spalte Ihrer Datenbank speichern (in unserem Fall wären es 3).

Innerhalb Ihrer Anwendung benötigen Sie lediglich eine weitere bitweise Operation (OR), um zu überprüfen, ob ein Benutzer über eine bestimmte Berechtigung verfügt oder nicht.

Andere Tipps

Normalerweise gehe ich beim Codieren von Berechtigungssystemen mit 6 Tabellen vor.

  • Benutzer – das ist ziemlich einfach, es ist Ihre typische Benutzertabelle
  • Gruppen – das würde auch für Ihre Abteilungen gelten
  • Rollen – Dies ist eine Tabelle mit allen Berechtigungen, im Allgemeinen auch einschließlich eines für Menschen lesbaren Namens und einer Beschreibung
  • Users_have_Groups – Dies ist eine Viele-zu-Viele-Tabelle, die angibt, zu welchen Gruppen ein Benutzer gehört
  • Users_have_Roles – eine weitere Many-to-Many-Tabelle darüber, welche Rollen einem einzelnen Benutzer zugewiesen sind
  • Groups_have_Roles – die letzte Viele-zu-Viele-Tabelle mit den Rollen, die jede Gruppe hat

Zu Beginn einer Benutzersitzung würden Sie eine Logik ausführen, die alle ihnen zugewiesenen Rollen abruft, entweder über ein Verzeichnis oder über eine Gruppe.Anschließend programmieren Sie diese Rollen als Ihre Sicherheitsberechtigungen.

Wie gesagt, das mache ich normalerweise, aber Ihre Menge kann variieren.

Zusätzlich zu den Lösungen von John Downey und jdecuyper habe ich am Ende/Anfang des Bitfelds auch ein „Explicit Deny“-Bit hinzugefügt, sodass Sie zusätzliche Berechtigungen nach Gruppe und Rollenmitgliedschaft ausführen und dann Berechtigungen basierend auf der expliziten Ablehnung subtrahieren können Einträge, ähnlich wie NTFS funktioniert, berechtigungsmäßig.

Ehrlich gesagt würden die ASP.NET-Mitgliedschafts-/Rollenfunktionen perfekt für das von Ihnen beschriebene Szenario funktionieren.Das Schreiben eigener Tabellen/Procs/Klassen ist eine tolle Übung und man kann sehr gute Kontrolle über kleinste Details bekommen, aber nachdem ich das selbst gemacht habe, bin ich zu dem Schluss gekommen, dass es besser ist, einfach die eingebauten .NET-Sachen zu verwenden.Ein großer Teil des vorhandenen Codes ist darauf ausgelegt, ihn zu umgehen, was auch gut ist.Das Schreiben von Grund auf hat mich etwa zwei Wochen gekostet und es war bei weitem nicht so robust wie .NETs.Sie müssen so viel Mist programmieren (Passwortwiederherstellung, automatische Sperrung, Verschlüsselung, Rollen, eine Berechtigungsschnittstelle, jede Menge Prozesse usw.), und die Zeit könnte besser woanders verbracht werden.

Tut mir leid, wenn ich Ihre Frage nicht beantwortet habe. Ich bin wie der Typ, der sagt, er solle C# lernen, wenn jemand eine VB-Frage stellt.

Ein Ansatz, den ich in verschiedenen Anwendungen verwendet habe, besteht darin, eine generische PermissionToken-Klasse zu haben, die über eine veränderbare Value-Eigenschaft verfügt.Anschließend fragen Sie die angeforderte Anwendung ab. Diese teilt Ihnen mit, welche PermissionTokens für die Verwendung erforderlich sind.

Die Versandanwendung könnte Ihnen beispielsweise mitteilen, dass Folgendes erforderlich ist:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

Dies kann natürlich auf Erstellen, Bearbeiten, Löschen usw. erweitert werden, und aufgrund der benutzerdefinierten Value-Eigenschaft kann jede Anwendung, jedes Modul oder jedes Widget ihre eigenen erforderlichen Berechtigungen definieren.YMMV, aber das war für mich schon immer eine effiziente Methode, die sich meiner Meinung nach gut skalieren lässt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top