2011-10-20 17 views
11

Nella mia applicazione MVC Ho un paio di ruoli diversi: Admin, utente generale, ecc, eccSicurezza in MVC Visualizzazioni

So che posso applicare la protezione ai miei controllori tramite l'attributo Autorizza:

[Authorize(Roles="Admin")] 
public ActionResult Create() 
{ 
    return View(); 
} 

Ma ho anche bisogno di applicare una certa sicurezza agli Visualizzazioni per non visualizzare alcune sezioni della vista per certi ruoli:

@if(User.IsInRole("Admin")) 
{ 
    @Html.ActionLink("Create", "Create") 
} 

è meglio farlo nel modo di cui sopra, o gestire questo tipo di SECURI Ty in una ViewModel:

public ActionResult Index() 
{ 
    var model = new IndexViewModel(); 

    model.CanCreate = User.IsInRole("Admin"); 

    return View(model); 
} 

View: 
@(Model.CanCreate) 
{ 
    @Html.ActionLink("Create", "Create") 
} 

Ha il secondo metodo hanno alcun beneficio rispetto al primo o è solo una cosa preferenza?

+0

penso primo metodo è migliore. – Birey

risposta

6

Il secondo modo è più preferito, in quanto la logica aziendale rimarrà a livello di modello.

Nel tuo esempio, la logica di business è molto semplice. Tuttavia, immagina che i requisiti siano cambiati e che ora non solo gli amministratori possono creare contenuti, ma anche utenti generici che hanno effettuato la registrazione più di 1 mese fa. Tenendo presente la logica aziendale, è necessario aggiornare tutte le visualizzazioni.

1

Potrebbe essere necessario sia ...

Si noti che solo il 2 ° non sarebbe sicuro, un utente potrebbe essere in grado di costruire l'URL per l'ActionLink nei browser AddressBar. Quindi hai assolutamente bisogno dell'attributo per sicurezza.

Il secondo è più una questione di facilità d'uso o progettazione dell'interfaccia utente. Forse vuoi che l'utente sia in grado di fare clic su Crea e quindi avere una scelta per accedere in modo diverso.

+0

Non intendevo dire che non avrei messo [Autorizza] sulle azioni. La domanda era se dovessi gestire la mia sicurezza di Vista includendo le proprietà nel modello o mettendo direttamente le chiamate User.IsInRole() nella mia vista. – Dismissile

0

Controllare l'autorizzazione nel controller e preparare Viewmodel per la visualizzazione in base alle regole del proprio ruolo.

Le viste vengono utilizzate per mostrare semplicemente i dati. Quindi, non sono obbligati a fare il controllo dei ruoli, ecc.

Quindi preparare ViewModel con i dati che dovrebbe avere e lasciare che la vista lo renda solo. (la proprietà booleana che stai utilizzando è sufficiente)

3

Un modo in cui l'ho fatto prima è la creazione di un filtro azione che eredita da AuthorizeAttribute. Il filtro può essere chiamato qualcosa come DisplayIfAuthorizedAttribute e, oltre alle proprietà AuthorizeAttribute standard, ha una proprietà denominata ViewNameIfNotAuthorized.

L'attributo chiama il metodo di base per eseguire l'autorizzazione e, in caso di errore, restituisce la vista ViewNameIfNotAuthorized. Altrimenti, consente al metodo di azione di procedere normalmente.

Effettuare il rendering di queste viste parziali tramite i metodi di azione e chiamare i metodi di azione tramite Html.RenderAction o Html.Action nella visualizzazione padre. Questi metodi di azione verrebbero decorati con l'attributo.

Ora avete un modo standardizzato per fare questo e nessun codice di autorizzazione che inquina i componenti interni dei vostri metodi di azione.

Questo è ciò che il filtro sarà simile:

public class DisplayIfAuthorizedAttribute : System.Web.Mvc.AuthorizeAttribute 
{ 
    private string _ViewNameIfNotAuthorized; 
    public DisplayIfAuthorizedAttribute(string viewNameIfNotAuthorized = null) 
    { 
     _ViewNameIfNotAuthorized = viewNameIfNotAuthorized; 
    } 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     bool isAuthorized = base.AuthorizeCore(filterContext.HttpContext); 

     if (!isAuthorized) 
     { 
      filterContext.Result = GetFailedResult(); 
     } 
    } 

    private ActionResult GetFailedResult() 
    { 
     if (!String.IsNullOrEmpty(_ViewNameIfNotAuthorized)) 
     { 
      return new ViewResult { ViewName = _ViewNameIfNotAuthorized }; 
     } 
     else 
      return new EmptyResult(); 
    } 
} 

tuo metodo di azione sarebbe decorare come:

[DisplayIfAuthorized("EmptyView", Roles="Admin")] 
     public ViewResult CreateLink() 
     { 
      return View("CreateLink"); 
     } 
Problemi correlati