Wie erstelle ich ein benutzerdefiniertes AuthorizeAttribute, das für den Bereich, den Controller und die Aktion spezifisch ist?

7

Mit anderen Worten, ist das eine wirklich dumme Idee?

%Vor%

UPDATE Ich versuche, in einem Szenario, in dem wir extrem granulare Rollenberechtigungen haben, Folgendes zu vermeiden: Die Rollen werden pro Client eingerichtet und an Benutzergruppen angehängt:

%Vor%

Kann mich jemand auf eine sichere Weise aufklären, um dieses AuthorizeRouteAttribute zu schreiben, um auf die Routeninformationen zuzugreifen und diesen als Rollennamen zu verwenden? Wie Levi sagt, ist der RouteData.Values ​​nicht sicher.

Ist die Verwendung des ausführenden httpContext.Request.Path sicherer oder besser?

%Vor%

Dies veranschaulicht vielleicht das Problem ein wenig weiter:

%Vor%     
Junto 03.02.2011, 17:36
quelle

3 Antworten

18

Bitte tu das nicht .

Wenn es wirklich notwendig ist, können Sie den Type des Controllers oder die MethodInfo der Aktion verwenden, um Sicherheitsentscheidungen zu treffen. Aber alles von Strings zu befreien, verlangt nach Ärger. Denken Sie daran, dass es keine 1: 1-Zuordnung von Routing-Werten zum tatsächlichen Controller gibt. Wenn Sie das Routing-Tupel (a, b, c) verwenden, um den Zugriff auf SomeController :: SomeAction zu validieren, aber jemand entdeckt, dass (a, b ', c) auch dieselbe Aktion ausführt, kann diese Person Ihre Sicherheitsmechanismen umgehen.

Bearbeiten , um auf Kommentare zu antworten:

Sie haben über die ActionDescriptor-Eigenschaft des filterContext -Parameters Zugriff auf den Typ des Controllers und die MethodInfo der Aktion. Dies ist der einzige sichere Weg, um zu bestimmen, welche Aktion wirklich ausgeführt wird, wenn die MVC-Pipeline verarbeitet wird, weil es möglich ist, dass Ihre Suche nicht exakt mit den Hintergründen von MVC übereinstimmt. Sobald Sie den Typ / MethodInfo / was auch immer haben, können Sie die gewünschten Informationen (wie beispielsweise ihre voll qualifizierten Namen) verwenden, um Sicherheitsentscheidungen zu treffen.

Als praktisches Beispiel betrachten Sie einen Bereich MyArea mit einem Controller FooController und einer Aktion TheAction. Normalerweise würden Sie diese FooController :: TheAction über diese URL treffen:

  

/ MeineArea / Foo / TheAction

Und Routing gibt das Tupel (Area="MyArea", Controller="Foo", Aktion="TheAction").

Sie können FooController :: TheAction aber auch über diese URL drücken:

  

/ Foo / TheAction

Und Routing wird das Tupel geben (Area="", Controller="Foo", Action="TheAction"). Denken Sie daran, dass Bereiche Routen zugeordnet sind, nicht Controller. Und da ein Controller von mehreren Routen betroffen sein kann (wenn die Definitionen übereinstimmen), kann ein Controller auch mehreren Bereichen logisch zugeordnet werden. Aus diesem Grund weisen wir Entwickler an, niemals Routen (oder Bereiche oder das Tag & lt; location & gt; durch Erweiterung) zu verwenden, um Sicherheitsentscheidungen zu treffen.

Außerdem gibt es einen Fehler in Ihrer Klasse, der veränderbar ist (er ändert seine eigene Roles-Eigenschaft in OnAuthorization). Aktionsfilterattribute müssen unveränderbar sein, da sie möglicherweise von Teilen der Pipeline zwischengespeichert und wiederverwendet werden können. Abhängig davon, wo dieses Attribut in Ihrer Anwendung deklariert ist, öffnet sich ein Timing-Angriff, den ein böswilliger Site-Besucher dann ausnutzen könnte, um sich selbst Zugriff auf beliebige Aktionen zu gewähren.

Weitere Informationen finden Sie auch in meinen Antworten unter:

Levi 03.02.2011, 18:54
quelle
5

Wenn Sie dies unter Berücksichtigung der Empfehlung von Levi tun möchten, lautet die Antwort wie folgt:

%Vor%

Ich wollte kein HttpUnauthorizedResult bereitstellen, wenn ein Benutzer nicht in der Rolle ist, weil das Ergebnis darin besteht, den Benutzer zur Anmeldeseite zu schicken. Wenn man bedenkt, dass sie bereits eingeloggt sind, ist das für den Benutzer sehr verwirrend.

    
Junto 08.02.2011 21:36
quelle
1

Dies ist eine kurze Nachricht! Verwenden Sie unbedingt filterContext.RouteData.DataTokens["area"]; anstelle von filterContext.RouteData.Values["area"];

Viel Glück.

    
QMaster 07.02.2013 16:59
quelle