sql - Was ist der beste Weg, um mit mehreren Berechtigungstypen umzugehen?

Translate

Ich stoße häufig 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. Angenommen, ich möchte entweder einer Abteilung oder nur einer bestimmten Person Zugriff auf eine Anwendung gewähren. Und tun Sie so, als hätten wir eine Reihe von Anwendungen, die ständig wachsen.

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

  1. Verwenden Sie eine einzelne Berechtigungstabelle mit speziellen Spalten, anhand derer festgelegt wird, wie die Parameter angewendet werden sollen. Die speziellen Spalten in diesem Beispiel sind TypeID und TypeAuxID. Das 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 jeden Berechtigungstyp eine Zuordnungstabelle und fügen 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 [email protected]
      AND ([email protected] OR [email protected] 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 machen. Ich habe sie zusammengeschustert.

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

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

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 mit dem bitweisen Operator AND mehrere Berechtigungen kombinieren.

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

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

Quelle
Translate

Die Art und Weise, wie ich normalerweise Berechtigungssysteme codiere, besteht aus 6 Tabellen.

  • Benutzer - das ist ziemlich einfach, es ist Ihre typische Benutzertabelle
  • Gruppen - das wäre gleichbedeutend mit Ihren Abteilungen
  • Rollen - Dies ist eine Tabelle mit allen Berechtigungen, die im Allgemeinen auch einen lesbaren Namen und eine Beschreibung enthält
  • Users_have_Groups - Dies ist eine Viele-zu-Viele-Tabelle der Gruppen, zu denen ein Benutzer gehört
  • Users_have_Roles - eine weitere Viele-zu-Viele-Tabelle, welche Rollen einem einzelnen Benutzer zugewiesen sind
  • Groups_have_Roles - die letzte Viele-zu-Viele-Tabelle der Rollen, die jede Gruppe hat

Zu Beginn einer Benutzersitzung würden Sie eine Logik ausführen, die jede von ihnen zugewiesene Rolle entweder im Verzeichnis oder über eine Gruppe herausholt. Anschließend codieren Sie diese Rollen als Ihre Sicherheitsberechtigungen.

Wie ich bereits sagte, ist dies das, was ich normalerweise mache, aber Ihre Millage kann variieren.

Quelle
Translate

Zusätzlich zu den Lösungen von John Downey und jdecuyper habe ich am Ende / Anfang des Bitfelds ein "Explicit Deny" -Bit hinzugefügt, damit Sie additive Berechtigungen nach Gruppe und Rollenmitgliedschaft ausführen und dann Berechtigungen basierend auf expliziter Verweigerung subtrahieren können Einträge, ähnlich wie NTFS, funktionieren mit Berechtigungen.

Quelle
Translate

Ehrlich gesagt würden die ASP.NET-Mitgliedschafts- / Rollenfunktionen für das von Ihnen beschriebene Szenario perfekt funktionieren. Das Schreiben eigener Tabellen / Prozesse / Klassen ist eine großartige Übung, und Sie können sehr gute Kontrolle über kleinste Details erlangen, aber nachdem ich dies selbst getan habe, bin ich zu dem Schluss gekommen, dass es besser ist, nur das eingebaute .NET-Material zu verwenden. Viel vorhandener Code wurde entwickelt, um ihn zu umgehen, was gut ist. Das Schreiben von Grund auf dauerte ungefähr 2 Wochen und es war nicht annähernd so robust wie .NETs. Sie müssen so viel Mist codieren (Passwortwiederherstellung, automatische Sperrung, Verschlüsselung, Rollen, eine Berechtigungsschnittstelle, Tonnen von Prozessen 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 soll c # lernen, wenn jemand eine vb-Frage stellt.

Quelle
Translate

Ein Ansatz, den ich in verschiedenen Anwendungen verwendet habe, besteht darin, eine generische PermissionToken-Klasse mit einer veränderbaren Value-Eigenschaft zu haben. Anschließend fragen Sie die angeforderte Anwendung ab und erfahren, welche PermissionTokens für die Verwendung erforderlich sind.

Beispielsweise kann die Versandanwendung Ihnen 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. Aufgrund der benutzerdefinierten Value-Eigenschaft kann jede Anwendung, jedes Modul oder Widget ihre eigenen erforderlichen Berechtigungen definieren. YMMV, aber dies war für mich immer eine effiziente Methode, die sich gut skalieren lässt.

Quelle