2009-08-22 7 views
9

Ich fragte mich, ob und wie ich das Standardverhalten [Autorisieren] in ASP.NET MVC überschreiben kann. Ich weiß, dass ich einen neuen Aktionsfilter erstellen, mein eigenes Attribut erstellen kann und so weiter; Ich bin nur interessiert, wenn ich einfach das Verhalten [Autorisieren] ändern und seine Arbeitsweise durch meinen eigenen Code ersetzen kann?Kann das Standardverhalten von [Authorize] in ASP.NET MVC überschrieben werden?

Bearbeiten: Jungs und Mädchen. Ich schätze Ihre Eingabe, aber wie ich schrieb, bin ich nicht Suche nach Einführung eines neuen [XYZAuthorize] Attribut. Ich bin mir bewusst, wie das geht. Ich möchte die [Authorize] -Notation behalten, aber nur ändern, wie es funktioniert.

+7

Warum möchten Sie den "authorize" -Namen des Attributs behalten und sein Verhalten ändern? Es ist eine schlechte Sache zu tun. Leute, wenn sie [Autorisieren] sehen, erwarten sie, was es tun wird. Wenn Sie es ändern, wird das Lesen Ihres Codes viel schwieriger. Auch für dich in der Zukunft. –

+3

Ich stimme nicht zu; Wenn Sie dies bestreiten, wäre ein Überladen/Überschreiben von Operatoren oder Methoden falsch. – Alex

+5

@Alex: Ich stimme nicht zu. Bedienerüberlastung ist eine gute Sache. Es ist eine schlechte Sache, es zu missbrauchen. Das übliche Beispiel: Sie haben eine Vector-Klasse, Sie erstellen den Operator "+". Es ist offensichtlich, was es tun wird. Aber was ist mit dem "*" Operator? Es ist eine schlechte Sache zu tun, ist es ein Cross-Produkt oder ein Dot-Produkt? Oder eine andere Art von benutzerdefiniertem Produkt? Also: Überladung ist gut, aber es ist sehr schlecht, wenn Sie Konventionen maskieren. –

Antwort

6

Ja, werfen Sie einen Blick auf die MSDN-Dokumentation für AuthorizeAttribute: http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx.

Grundsätzlich können Sie die OnAuthorization() -Methode überschreiben und das Verhalten anpassen. Es gibt andere virtuelle Methoden für das Attribut.

BEARBEITEN: Wie Bruno darauf hingewiesen hat, können Sie die AuthorizeCore() Methode überschreiben. Der Hauptunterschied besteht darin, dass AuthorizeCore() eine HttpContextBase akzeptiert, während OnAuthorization() einen AuthorizationContext akzeptiert. Eine Instanz von AuthorizationContext bietet Ihnen weitere Informationen, z. B. den Controller, den RequestContext und die RouteData. Sie können auch ein ActionResult angeben.

AuthorizeCore() ist in den Informationen eingeschränkt, auf die Sie zugreifen können, sowie auf das Ergebnis, das Sie zurückgeben können. Wenn Sie jedoch zwischengespeicherte Daten autorisieren müssen, muss Ihre Logik den Fall behandeln, in dem Sie keinen haben diese zusätzlichen Daten (da Daten aus dem Cache bereitgestellt werden, bevor die Anforderung durch die MVC-Pipeline geleitet wird).

Wie immer müssen Sie Ihr Szenario und die verfügbaren Tools und Trade-Offs zwischen ihnen verstehen.

+1

Das AuthorizeAttribute enthält keine OnAuthorize-Methode. Meinst du OnAuthorization()? Wie auch immer, Sie sollten es nicht ändern, es sei denn, Sie möchten beim Implementieren von Caching etwas Kopfschmerzen haben, da es diese eine Methode (OnAuthorization) ist, die damit umgeht. –

9

Sie können den AuthorizeAttribute-Filter ableiten und Ihre eigene Logik darin einfügen.

Lassen Sie uns ein Beispiel sehen. Nehmen wir an, Sie möchten immer lokale Verbindungen autorisieren. Wenn es sich jedoch um eine Remoteverbindung handelt, möchten Sie die übliche Berechtigungslogik beibehalten.

Man könnte so etwas wie tun:

public class LocalPermittedAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
     { 
      return (httpContext.Request.IsLocal || base.AuthorizeCore(httpContext))); 
     } 
} 

Oder Sie könnten eine bestimmte Remote-Adresse (Ihr Gerät, zum Beispiel) immer genehmigen.

Das war's!

Edit: vergaß zu erwähnen, werden Sie es die gleiche verwenden, wie Sie den AuthorizeAttribute Filter verwenden würde:

class MyController : Controller 
{ 
    [LocalPermittedAuthorize] 
    public ActionResult Fire() 
    { 
     Missile.Fire(Datetime.Now); 
    } 
} 
2

Ich sehe nur zwei Möglichkeiten: Ihr eigenes autorisieren Attribut von Grund auf übergeordnete AuthorizeAttribute.OnAuthorization Methode oder zu schaffen.

1) sehr einfach:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 

     /// your behavior here 
    } 
} 

2) leicht zu - nur Blick auf ASP.NET MVC Quelle, AuthorizeAttribute.cs Datei

+1

Sie sollten es vermeiden, ein autorisiertes Attribut von Grund auf neu zu erstellen, wenn Sie keine Kopfschmerzen haben wollen wird Caching implementieren ... das Attribut Authorize von ASP.NET MVC behandelt diesen Aspekt bereits. –

1

Es scheint, Sie können wie gewohnt einen benutzerdefinierten Filter implementieren (und AuthorizeAttribute erben, wenn Sie möchten) und dann einen neuen ActionInvoker erstellen, der ControllerActionInvoker erbt und GetFilters überschreibt.In GetFilters rufen Sie base.GetFilters() auf, um die Liste der Filter abzurufen, die Autorisierungsfilter durchlaufen und Aufrufe von AuthorizeFilter durch Aufrufe an Ihren benutzerdefinierten Filter zu ersetzen.

Eine andere Möglichkeit besteht darin, benutzerdefinierte Mitgliedschafts- und Rollenanbieter zu implementieren, je nachdem, was Sie tun möchten.

+0

Warum braucht man einen benutzerdefinierten ActionInvoker nur für einen einfachen Autorisierungsfilter? –

+0

@Bruno: Da scheint es keinen anderen Weg zu geben, einen Framework-Filter durch eigene zu ersetzen, nur um neue zu erstellen. – svinto

+0

Aber ... warum sollte man den Rahmenfilter * ersetzen *? Sieh meinen Kommentar zu der Frage. Es ist eine dumme Sache zu tun. –

4

Implementieren Sie Ihren eigenen Rollenanbieter und legen Sie Ihre App fest, um sie zu verwenden. Dann wird das Attribut Autorisieren Ihren Bestätigungscode berücksichtigen.