Granulare Berechtigungen mit bestimmten Anforderungen für eine MVC-Site

8

Ich mag die eingebauten Mitgliedschaftsanbieter nicht. Ich habe beschlossen, mein eigenes zu rollen. Ich versuche eine gute Methode zur Autorisierung auf Aktionsebene zu finden. Hier sind die Anforderungen, an die ich versuche zu gehen:

  1. Attributverwendung - Ich mag das, da es auf einer sehr hohen Ebene im Call-Stack kontrolliert und ein guter Ort ist, um Berechtigungen zu organisieren.
  2. Keine Zauberei - Das ist ein Grund, warum ich mich von den derzeitigen Rollenanbietern abwende. Ich möchte keine Strings herumliegen lassen, die nicht einfach umbenannt werden können.
  3. Berechtigungen sollten aus one anderen Berechtigungen bestehen. Beispiel: ReadWrite hat die Berechtigung für Read . Genau wie or'ing mit einem enum.

HINWEIS: Manche denken, dass diese Anforderungen zu weit gefasst sind (siehe Kommentare). Ich denke nicht, ich denke, sie sind ziemlich einfach.

Der größte Showstopper ist die Attributverwendung. Es kann nur "konstante Ausdrücke, Typof-Ausdrücke oder Array-Erstellungsausdrücke eines Attribut-Parametertyps" geben.

Ich dachte daran, vielleicht so etwas zu haben, damit Operationen statischen Zugriff haben. Innerhalb des Attributs würde es "int" in die tatsächliche Berechtigung oder etwas ... umwandeln:

%Vor%

Aber es begrenzt wirklich die Zusammensetzung. Ich bin mir sicher, dass du denkst: "Warum gehst du nicht auf die Enum-Route?" Nun, ich möchte planen, dass sich Dinge ändern und nicht auf 32 (int) oder 64 (lange) Operationen beschränkt werden wollen und später eine massive Neuschreibung durchführen müssen (auch in der db, die nur hässlich ist).

Auch wenn es eine bessere Alternative als Attribute für Aktionen / Controller gibt, bin ich auf der Suche nach Vorschlägen.

EDIT: Auch aus diesen Beitrag < Ich habe über die Klasse BitArray gelesen. Es scheint Art hässlich, besonders mit dem willkürlichen Speicher in der Datenbank.

    
TheCloudlessSky 05.12.2010, 16:01
quelle

3 Antworten

5

Zuerst muss ich Ihnen danken, dass Sie mich saugen, um das zu beantworten;)

Dies ist eine lange Antwort und nur ein Ausgangspunkt. Sie müssen herausfinden, wie Sie Benutzern Rollen zuweisen und sie in AuthenticateRequest neu erstellen können.

Wenn dies Ihre Frage nicht beantwortet, hoffe ich, dass es eine Inspiration sein wird. Viel Spaß!

Dekorieren Sie die Controller-Aktionen

Ich habe damit begonnen, die zwei Aktionen im Standard HomeController :

zu dekorieren %Vor%

Alle Benutzer in der ReadWrite-Rolle sollten dann Zugriff erhalten. Ich habe mich hier entschieden, eine Enum als typsicheren Platzhalter für die Magic Strings zu verwenden. Die Rolle dieses Enums ist nichts anderes als ein Platzhalter zu sein. Es gibt keine zusammengesetzten Enum-Werte, die irgendwo anders gepflegt werden müssen. Mehr dazu später.

%Vor%

Implementieren Sie ein neues Autorisierungsattribut

Da die Strings weg sind, brauche ich ein neues authorised-Attribut:

%Vor%

Der RoleSet umschließt einen Satz von Enum-Werten und überprüft, ob ein IPrincipal Mitglied eines dieser Werte ist:

%Vor%

Pflegen Sie Rollen

In CompositeRoleSet werden zusammengesetzte Rollen registriert und behandelt. CreateDefault() ist der Ort, an dem alle Composites registriert sind. Resolve() nimmt eine Liste von Rollen (Enum-Werte) und konvertiert die Composites in ihre einzelnen Gegenstücke.

%Vor%

Verkabelung

Wir brauchen einen authentifizierten Benutzer, an dem wir arbeiten können. Ich habe einen in global.asax betrogen und hart-codiert:

%Vor%

Schließlich brauchen wir ein IPrincipal , das all dies versteht:

%Vor%     
Thomas Eyde 30.12.2010 16:51
quelle
0

Scheint so, als wolltest du etwas sehr flexibles und unabhängig von was man verlangen kann für die Sicherheitsprüfung. Es hängt also davon ab, "wie weit du bereit bist".

Um Ihnen dabei zu helfen, die richtige Richtung einzuschlagen, empfehle ich Ihnen dringend, auf die Seite von Anspruchsbasierte Zugriffskontrolle zu schauen. Und nimm diesen Artikel als Ausgangspunkt und ASP. NET MVC Beispiel.

Denken Sie jedoch daran, dass es sich um ein komplexes Thema handelt. Sehr flexibel (sogar Federated Access Control ohne Codeänderungen möglich), aber komplex.

Wir mussten diesen Weg gehen, um unsere Apps vollständig von diesen "richtigen" Implementierungen auszuschließen. Alle unsere Systeme wissen, was sie "behaupten" müssen, um bestimmte Aktionen auszuführen, und fragen sie nach der bereitgestellten Benutzeridentität (was auch ein "Anspruch" ist). Rollen, Berechtigungen und andere Ansprüche können leicht in die App-spezifischen "Ansprüche" übersetzt werden, die für unsere Apps sinnvoll sind. Volle Flexibilität.

P.S. Es löst nicht die technischen Probleme von "magischen Strings" und ähnlichem (Sie müssen denken, dass dies von Ihrer Situation abhängt), sondern bietet Ihnen eine sehr flexible Zugriffskontrollarchitektur.

    
Vasilio Ruzanni 30.12.2010 17:06
quelle
0

Also @thomas scheint eine nette Antwort zu haben, aber es ist mehr die Anforderung, Enums zu verwenden, und das in Rollen, die IPricipal verstehen wird. Meine Lösung ist von unten nach oben, also können Sie die Lösung von Thomas verwenden, um IPrincipal

zu implementieren

Ich brauchte wirklich etwas, das dem ähnlich ist, was Sie wollen und hatte immer Angst vor Formularauthentifizierung (ja, Sie haben auch Angst und ich weiß es, aber hören Sie mir zu). Also habe ich immer meine eigene billige Authentifizierung mit Formularen ausgerollt, aber Viele Dinge haben sich geändert, während ich mvc (in den letzten paar Wochen) gelernt habe. Auth ist sehr dis getrennt und es ist sehr flexibel. Im Wesentlichen verwenden Sie nicht wirklich die Formsauth, sondern Ihre eigene Logik in das System.

Also hier ist, wie ich das anstellte, ( Vorsicht, ich bin selbst ein Lerner ).

Zusammenfassung:

  1. Sie werden einige Formen der auth-Klassen überschreiben, um Ihre eigenen Benutzer zu authentifizieren (Sie können sich sogar darüber lustig machen)
  2. Sie werden dann ein IIdentity erstellen.
  3. Sie laden GenericPrincipal mit einer Liste von Rollen in Strings (ich weiß, keine magischen Strings ... lesen Sie weiter)

Sobald Sie das oben genannte tun, versteht MVC genug, um Ihnen zu geben, was Sie wollen! Sie können jetzt [Authorize(Roles = "Write,Read")] über einen beliebigen Controller verwenden und MVC wird fast alles machen. Jetzt für keine magischen Zeichenfolgen, alles, was Sie tun müssen, erstellen Sie einen Wrapper um dieses Attribut.

Lange Antwort

Sie verwenden die mit MVC gelieferte Internetanwendungsvorlage. Zuerst erstellen Sie zunächst ein MVC-Projekt, im neuen Dialogfeld sagen Sie eine Internetanwendung .

Wenn Sie die Anwendung überprüfen, wird eine Hauptklasse die Formularauthentifizierung außer Kraft setzen. IMembershipService Entferne die lokale MembershipProvider-Variable __provider_, und in dieser Klasse solltest du zumindest der ValidateUser -Methode Logik hinzufügen. (Versuchen Sie, einem Benutzer / Ausweis eine gefälschte Authentifizierung hinzuzufügen.) Sehen Sie auch die Standard-v-Testanwendung, die in VS erstellt wurde.

Implementieren Sie IIdentity

%Vor%

Denken Sie daran, dass wir weiterhin die Standardvorlage für Internetanwendungen verwenden, die mit einem MVC-Projekt geliefert wird.

Nun sollte AccountController.LogOn () also so aussehen:

%Vor%

Sie legen also ein Formularticket wie eine Sitzung an und lesen es dann bei jeder Anfrage wie folgt aus: Setzen Sie dies in Global.asax.cs

%Vor%

Ich fragte eine Frage, wie effizient und korrekt die oben genannte Methode war "database-on-all-request-asp-net"> hier .

Ok, jetzt bist du fast fertig, du kannst deine Controller so dekorieren: [Authorize(Roles="RoleA,RoleB")] (mehr zu den Strings später)

Es gibt hier ein kleines Problem, wenn Sie Ihren Controller mit AuthorizeAttribute dekorieren und der angemeldete Benutzer keine bestimmte Berechtigung hat, anstatt "Zugriff verweigert" zu sagen, wird der Benutzer standardmäßig sein auf die Anmeldeseite weitergeleitet, um sich erneut anzumelden. Du behebst das so (ich habe das aus einer SO-Antwort herausgehakt):

%Vor%

Nun fügen Sie nur noch einen weiteren Wrapper um AuthorizeAttribute hinzu, um starke Typen zu unterstützen, die in die Zeichenfolgen übersetzt werden, die Principal erwartet. Siehe diesen Artikel für mehr .

Ich plane, meine Anwendung zu aktualisieren, um später starke Typen zu verwenden. Ich werde diese Antwort dann aktualisieren.

Ich hoffe, es hat geholfen.

    
gideon 30.12.2010 18:34
quelle

Tags und Links