2011-10-20 14 views
11

En mi aplicación MVC tengo unos papeles diferentes: admin, usuario general, etc., etc.Seguridad en MVC Vistas

Sé que puedo aplicar seguridad a mis controladores a través del atributo Autorizar:

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

Pero también tengo que aplicar un poco de seguridad a las Vistas para no mostrar ciertas secciones de la vista a ciertos roles:

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

¿es mejor hacerlo de la manera anterior, o manejar este tipo de securi ty en un modelo de vista:

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

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

    return View(model); 
} 

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

¿El segundo método tiene los beneficios en comparación con el primer o es sólo una cosa de preferencia?

+0

Creo primer método es mejor. – Birey

Respuesta

6

La segunda forma es más preferida, ya que su lógica comercial se mantendrá a nivel de modelo.

En su ejemplo, la lógica de negocios es muy simple. Sin embargo, imagine que los requisitos han cambiado y ahora no solo los administradores pueden crear contenido, sino también los usuarios generales que se registraron hace más de 1 mes. Con la lógica de negocios a la vista, debería actualizar todas sus vistas.

1

Es posible que tenga tanto ...

Nota que el segundo uno por sí solo no sería seguro, un usuario podría ser capaz de construir la dirección URL de la ActionLink en los navegadores Addressbar. Entonces necesitas absolutamente el atributo de seguridad.

El segundo es más una cuestión de facilidad de uso o diseño de interfaz de usuario. Quizás desee que el usuario pueda hacer clic en Crear y luego tener la opción de iniciar sesión de manera diferente.

+0

No quise decir que no pondría [Autorizar] en las acciones. La pregunta era si debería manejar mi seguridad de Vista al incluir propiedades en el modelo o al poner directamente las llamadas User.IsInRole() en mi vista. – Dismissile

0

Compruebe la autorización en su controlador y prepare Viewmodel para la vista de acuerdo con las reglas de su rol.

Las vistas se utilizan simplemente para mostrar datos. Por lo tanto, no es necesario que revisen los roles, etc.

Prepare el ViewModel con los datos que debería tener y deje que la Vista solo lo represente. (la propiedad booleana que está utilizando es suficiente)

3

Una forma en que he hecho esto anteriormente es crear un filtro de acción que herede de AuthorizeAttribute. El filtro se puede denominar como DisplayIfAuthorizedAttribute y, además de las propiedades de AuthorizeAttribute estándar, tiene una propiedad llamada ViewNameIfNotAuthorized.

El atributo llama al método base para realizar la autorización, y si falla, devuelve la vista ViewNameIfNotAuthorized. De lo contrario, permite que el método de acción proceda normalmente.

A continuación, representará estas vistas parciales mediante métodos de acción, y llamará a los métodos de acción a través de Html.RenderAction o Html.Action en su vista principal. Esos métodos de acción estarían decorados con el atributo.

Ahora tiene una forma estandarizada de hacer esto y ningún código de autorización contamina las partes internas de sus métodos de acción.

Esto es lo que el filtro se vería así:

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(); 
    } 
} 

su método de acción se decoran como:

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