0

Ich habe folgende Datenbankstruktur DB structure, authentication/authorization part und ich muss Authentifizierung/Autorisierung für eine ASP.NET MVC 5-Site aufzubauen.Benutzerdefinierte Authentifizierung und Autorisierung in ASP.NET MVC5?

Der DB-Schema funktioniert wie folgt: jeder user zu einem group gehört, und jeder group kann gewährt werden/verweigert eine permission. Jede Berechtigung eine Aktion auf einem Controller übereinstimmt (sagen wir mal, ein Petitions Controller würde die folgenden Aktionen haben: List, View, Add, Edit, Delete, VoteFor, VoteAgainst, Reject und Approve, und jede Aktion ist ein Eintrag in der Permissions Tabelle) .

Der Zweck all dessen ist, dass die Site jedes Mal, wenn ein Benutzer eine Aktion aufruft, überprüft, ob der Benutzer zu einer Gruppe gehört, der die Berechtigung für diese Aktion erteilt wurde, und reagiert entsprechend.

Ein Beispiel: Angenommen, der Administrator gewährt die PetitionsList, PetitionsView, PetitionsApprove und PetitionsReject Berechtigungen für die Managers Gruppe und die PetitionsList, PetitionsView, PetitionsAdd, PetitionsVoteFor und PetitionsVoteAgainst zur Users Gruppe.

In diesem Fall können beide Gruppen

  • Liste Petitionen
  • sehen eine Petition

Manager

  • eine Petition
  • eine Petition ablehnen genehmigen kann

aber sie können nicht

  • Stimme für eine Petition
  • Votum gegen eine Petition.

In gleicher Weise können die Benutzer

  • für eine Petition
  • Votum gegen eine Petition

eine Petition

  • Stimme hinzufügen, aber sie können es nicht:

    • genehmigen eine Petition
    • lehnt eine Petition

    und weder kann eine Petition bearbeiten oder löschen.

    Ich würde wirklich die Attribute Funktionalität in MVC 5 nutzen möchte.Meine Idee ist, benutzerdefinierte Attribute zu erstellen, die die gesamte Authentifizierung/Autorisierung hinter Szenen durchführen. So etwas wie dieses:

    public class PetitionsController : Controller 
    { 
        [MyCustomAuth(Permission="PetitionsList",Groups="Users,Managers")] 
        public ActionResult List() 
        { 
         //show the list of petitions 
        } 
    
        [MyCustomAuth(Permission="PetitionsView",Groups="Users,Managers")] 
        public ActionResult View() 
        { 
         //show a specific petition 
        } 
    
        [MyCustomAuth(Permission="PetitionsAdd",Groups="Users")] 
        public ActionResult Add() 
        { 
         //show add petition form 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsAdd",Groups="Users")] 
        public ActionResult Add(object[] params) 
        { 
         //save new petition 
        } 
    
        [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")] 
        public ActionResult Edit(int id) 
        { 
         //show edit petition form 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")] 
        public ActionResult Edit(object[] params) 
        { 
         //save changes to petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsDelete",Groups="Admins")] 
        public ActionResult Delete(int_id) 
        { 
         //delete petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsVoteFor",Groups="Users")] 
        public ActionResult VoteFor(int id) 
        { 
         //add vote supporting petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsVoteAgainst",Groups="Users")] 
        public ActionResult VoteAgainst(int id) 
        { 
         //add vote against petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsApprove",Groups="Managers")] 
        public ActionResult Approve(int id) 
        { 
         //approve petition 
        } 
    
        [HttpPost] 
        [MyCustomAuth(Permission="PetitionsReject",Groups="Managers")] 
        public ActionResult Reject(int id) 
        { 
         //reject petition 
        } 
    } 
    

    Bitte beachten Sie die MyCustomAuth Attribut über jede Aktion. Ich möchte, dass dieses Attribut das schwere Heben des Sagens macht, wenn der Benutzer tatsächlich autorisiert ist, diese Aktion hinter den Kulissen auszuführen. Für den Fall, dass es nicht authentifiziert/autorisiert ist, sollte das Attribut natürlich zur Anmeldeseite/401/woanders umleiten.

    Meine Frage ist, wo fange ich an? Muss ich eine spezielle Schnittstelle implementieren/von einer Klasse in MVC 5 erben? Oder muss ich das von Grund auf neu schreiben?

    Auch, danke im Voraus für das Lesen dieser Wand des Textes und dafür, mir irgendwelche Tipps/Hinweise in die richtige Richtung zu geben.

  • +0

    Allgemeine Datenbank Zugangscode sollte nicht in Attribute sein (kann nicht Unit-Test des Code), so dass eine bessere Lösung wäre, hat Ein Dienst, der einen Wert zurückgibt, der angibt, ob der Benutzer die richtige Berechtigung hat. Der Code in jeder Controller-Methode könnte etwas wie 'if (! _permissionService.HasPermission (DocumentType.Petitions, ActionType.Edit, user.ID) {// verweigert} ' –

    +0

    Wie wäre es mit der Erstellung eines Dienstes, der überprüft, ob der Benutzer Zugriff auf die angegebene Aktion und Aufruf des Dienstes von der Attributklasse? Erleichtert das Testen der Verifikation und ich schreibe immer nur ein Attribut über die Aktion (das Beste aus beiden Welten?) –

    +0

    Stellen Sie sicher, dass Sie DI verwenden können, damit Ihre Controller es können Seien Sie vereinheitlicht und testen Sie die 2 wichtigsten Antworten [hier] (http://stackoverflow.com/questions/7192543/injecting-dependencies-into-asp-net-mvc-3-action-filters-whats-wrong- mit diesem) –

    Antwort

    1

    Ich denke, Sie können unten mit benutzerdefinierten Autorisierungsfilter beginnen. Es behandelt auch Fälle für beide - Ajax-Anfrage und vollständige Seitenanforderung.

    public class MyCustomAuthAttribute : FilterAttribute, IAuthorizationFilter 
        { 
         public string Permission { get; set; } 
         public string Groups { get; set; } 
    
         public void OnAuthorization(AuthorizationContext filterContext) 
         { 
          bool isauthorized = CheckIfUserIsAuthorized(); 
          if (!isauthorized) 
           context.Result = new HttpUnauthorizedResult(); // mark unauthorized 
    
          // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
          if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest()) 
          { 
           filterContext.Result = new JsonResult 
           { 
            Data = new { Success = false, Message = "Unauthorized Access" }, 
            JsonRequestBehavior = JsonRequestBehavior.AllowGet 
           }; 
          } 
          else 
          { 
           base.OnAuthorization(filterContext); 
           if (filterContext.Result is HttpUnauthorizedResult) 
           { 
            HttpContext.Current.Session.Abandon(); 
            System.Web.Security.FormsAuthentication.SignOut(); 
            filterContext.Result = new RedirectResult("Your Login Page."); 
           } 
          } 
         } 
    
         private bool IsAuthorizedUser() 
         { 
          // use Permission, Groups and your logic 
         } 
        } 
    

    und es auf die gleiche Weise verwenden, die Sie erwähnten:

    [MyCustomAuth(Permission="PetitionsEdit",Groups="Admins")] 
    
    Verwandte Themen