13

Ich baue einen einfachen CMS, in dem Rollen dynamisch im Admin-Panel gesetzt werden. Die bisherige Art der Autorisierung einer Controller-Methode, zB [Authorize(Roles="admin")], ist damit nicht mehr ausreichend. Die Rollen-Aktions-Beziehung muss in der Datenbank gespeichert werden, sodass Endbenutzer im Admin-Steuerfeld leicht Berechtigungen für andere Benutzer erteilen können. Wie kann ich das umsetzen?ASP.NET MVC - Dynamische Autorisierung

Antwort

0

Das ist genau das, was das ASP.NET-Mitgliedschafts-/Profil-Zeug für Sie tut. Und es funktioniert mit dem Autorize-Attribut.

Wenn Sie Ihre eigenen Rollen erstellen möchten, können Sie einen benutzerdefinierten Aktionsfilter erstellen, der das Verhalten des standardmäßigen Autorisierungsaktionsfilters nachahmt. Pseudocode unten.

public MyAuthorizeAttribute : ActionFilterAttribute 
{ 
    public string MyRole { get; set; } 

    public void OnActionExecuting(ControllerContext context) 
    { 
     if (!(bool)Session["userIsAuthenticated"]) 
     { 
      throw new AuthenticationException("Must log in."); 
     } 

     if (!Session["userRoles"].Contains(MyRole)) 
     { 
      throw new AuthenticationException("Must have role " + MyRole); 
     } 
    } 
} 
+0

Ich bin ziemlich neu in diesem Zeug, aber ich sah ein Beispiel, wo die Rolle speziell im Code zugewiesen wurde, und ich will das nicht. Beispielsweise könnte ein Client eine Benutzergruppe namens "Engineer" mit bestimmten Berechtigungen haben. Ich möchte, dass er sie über das Admin-Panel einrichten kann, ohne irgendeinen Code zu berühren. Im Moment kann ich nicht sehen, wie Sie das Autorize-Standardattribut dafür verwenden können – xantrus

+0

Danke, ich werde es überprüfen – xantrus

+0

Gut, dann müssten Sie Lookups in Ihrer Datenbank irgendwann hinzufügen, vielleicht passen Sie den Benutzer und Controller/Aktionsnamen mit einer Zugriffsregel, die Sie in der DB haben. Oder etwas ähnliches. – rmac

0

Die Rolle - Wirkungs-Beziehung in der Datenbank gespeichert werden müssen

Sie Ihre Sicherheit innerhalb der Controller-Methode haben zu überprüfen, es sei denn, Sie AuthorizeAttribute so Unterklasse wollen, dass es nach oben schaut die Rollen aus der Datenbank für dich.

18

Wenn Sie die Kontrolle über den Autorisierungsprozess übernehmen möchten, sollten Sie die Unterklasse AuthorizeAttribute absetzen und die Methode AuthorizeCore überschreiben. Dann dekorieren Sie einfach Ihre Controller mit Ihrem CmsAuthorizeAttribute anstelle der Standardeinstellungen.

public class CmsAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override virtual bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     IPrincipal user = httpContext.User; 
     IIdentity identity = user.Identity; 

     if (!identity.IsAuthenticated) { 
      return false; 
     } 

     bool isAuthorized = true; 
     // TODO: perform custom authorization against the CMS 


     return isAuthorized; 
    } 
} 

Der Nachteil ist, dass Sie keinen Zugriff auf Ctor-injizierten IoC haben, so dass Sie direkt alle Abhängigkeiten aus dem Behälter anfordern müssen.

+0

Was ist der Nachteil, Abhängigkeiten direkt vom Container zu bekommen? Ich musste dies für meine RoleProvider-Implementierung haben ... – Haroon

+1

@Haroon - Der Nachteil ist eine der Design. Es wird allgemein als Best Practice für Code betrachtet, den IoC-Container nicht zu kennen, um seine Abhängigkeiten zu reduzieren (z. B. möchten Sie möglicherweise Ihren Code auf WP7 wiederverwenden, bei dem ein reflektionsbasierter Container aus Leistungsgründen in der Regel vermieden wird). –

+0

@Haroon - Nachdem das gesagt wurde, unterstützt MVC 3 die Filterattributinjektion über attributverzierte Eigenschaften. Es erfordert immer noch Kenntnisse über den Container, aber es wird leichter verspottet. –