2010-01-15 5 views
34

Ich habe einen Controller mit einem AuthorizeAttribute dekoriert. Der Controller enthält mehrere Aktionen, die alle Authentifizierung erfordern, abgesehen von einer Aktion, die eine benutzerdefinierte Authentifizierung erfordert, die von CustomAuthorizeAttribute bereitgestellt wird.Controller überschreiben AuthorizeAttribute für nur eine Aktion

Meine Frage ist, sobald ich [Autorisieren] auf der Controller-Ebene hinzugefügt habe, kann ich es überschreiben (oder entfernen) mit [CustomAuthorize] auf nur eine Aktion? Oder muss ich [Authorize] von der Controller-Ebene entfernen und sie jeder anderen Aktion einzeln hinzufügen?

Ich frage rein aus Bequemlichkeit, weil ich faul bin und nicht jede Aktion mit dem AuthorizeAttribute dekorieren will.

[Authorize] 
public class MyController : Controller { 

    //requires authentication 
    public ViewResult Admin() { 
    return View(); 
    } 

    //... a lot more actions requiring authentication 

    //requires custom authentication 
    [CustomAuthorize] //never invoked as already failed at controller level 
    public ViewResult Home() { 
    return View(); 
    } 

} 

Antwort

17

können Sie die Reihenfolge ändern, in der die Attribute laufen (die Order-Eigenschaft verwendet wird), aber ich glaube, dass sie in diesem Fall immer noch beide laufen, wenn man nicht ein Ergebnis mit sofortiger Wirkung erzeugt. Der Schlüssel besteht darin, das am wenigsten restriktive Attribut auf die höchste Ebene (Klasse) anzuwenden und für die Methoden restriktiver zu werden. Wenn Sie beispielsweise die Aktion Home öffentlich verfügbar machen möchten, müssen Sie das Autorize-Attribut aus der Klasse entfernen und es auf jede der anderen Methoden anwenden.

Wenn die Aktion das gleiche Maß an Zulässigkeit hat, aber ein anderes Ergebnis hat, kann das Ändern der Reihenfolge ausreichend sein. Zum Beispiel würden Sie normalerweise auf die Aktion Logon umleiten, aber für Home möchten Sie auf die Aktion About umleiten. Geben Sie in diesem Fall das Klassenattribut Order=2 und das Home Aktionsattribut Order=1.

+0

In diesem Fall wird die CustomAuthorizeAttribute das gleiche Maß an Zugang bietet aber wird verwendet, um einen Fehler in Flash zu kompensieren und so den Auftrag einstellen Eigenschaften sind genug, um das gewünschte Ergebnis zu erzielen. Vielen Dank. –

+0

Durch die Reihenfolge des Attributs in der Aktion konnte ich das Attribut auf dem Controller überschreiben. Upvote! –

12

Nach viel zu viel Zeit, kam ich auf eine Lösung. Sie müssen Ihren Controller mit einem benutzerdefinierten AuthorizeAttribute dekorieren.

public class OverridableAuthorize : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     var action = filterContext.ActionDescriptor; 
     if(action.IsDefined(typeof(IgnoreAuthorization), true)) return; 

     var controller = action.ControllerDescriptor; 
     if(controller.IsDefined(typeof(IgnoreAuthorization), true)) return; 

     base.OnAuthorization(filterContext); 
    } 
} 

die mit IgnoreAuthorization über einen Aktions gepaart werden kann

public class IgnoreAuthorization : Attribute 
{ 
} 
+3

'IgnoreAuthorization'? Du meinst "Allow Anonymous"? – AgentFire

+0

'AllowAnonymous' ist was ich brauchte. Danke, @agentfire –

+0

Ja, ich wollte sagen, dass die genaue Logik bereits in die OnAuthorization-Methode von AuthorizeAttribute integriert ist ... außer dass das Attribut, nach dem es sucht, AllowAnonymous ist. Dies ist jedoch ein großartiges Beispiel dafür, wie Sie die starre UND-Logik, die normalerweise angewendet wird, außer Kraft setzen können. Damit könnten Sie ein Attribut vom Typ FancyAuthorizeAttribute mit einem Parametersatz auf den Controller anwenden und es dann auch auf eine einzelne Controller-Methode mit anderen Parametern anwenden, und OnAuthorization würde das Attribut auf Aktionsebene erkennen und die Controller-Ebene überspringen ein. – Triynko

66

In MVC 5 Sie die Berechtigung für jede Aktion außer Kraft setzen können das neue Attribut OverrideAuthorization verwenden. Grundsätzlich fügen Sie es einer Aktion hinzu, die eine andere Berechtigungskonfiguration als die im Controller definierte hat.

Sie tun es wie folgt aus:

[OverrideAuthorization] 
[Authorize(Roles = "Employee")] 
public ActionResult List() { ... } 

Weitere Informationen unter http://www.c-sharpcorner.com/UploadFile/ff2f08/filter-overrides-in-Asp-Net-mvc-5/

+3

Perfekt, genau was benötigt wurde! – user1477388

+0

Beachten Sie, dass dadurch auch globale Authentifizierungsfilter unterdrückt werden. Alle globalen Filter, die IAuthorizationFilter implementieren, werden deaktiviert. – ajbeaven

+0

irgendeine Alternative in asp.net Kern? – shashwat