2009-04-23 10 views
26

Tengo un controlador y me gustaría solicitar la Autorización para todas las acciones por defecto, excepto un par. Por lo tanto, en el siguiente ejemplo, todas las acciones deben requerir autenticación, excepto el índice. No quiero decorar cada acción con Authorize, solo quiero anular la autorización predeterminada en ciertas circunstancias, probablemente con un filtro personalizado como NotAuthorize.ASP MVC Autoriza todas las acciones excepto algunas

[Authorize] 
public class HomeController : BaseController 
{ 
    [NotAuthorize] 
    public ActionResult Index() 
    { 
     // This one wont 
     return View(); 
    } 

    public ActionResult About() 
    { 
     // This action will require authorization 
     return View(); 
    } 
} 

Respuesta

37

Ok, esto es lo que hice. Si hay una mejor manera házmelo saber.

public class NotAuthorizeAttribute : FilterAttribute 
{ 
    // Does nothing, just used for decoration 
} 

public class BaseController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Check if this action has NotAuthorizeAttribute 
     object[] attributes = filterContext.ActionDescriptor.GetCustomAttributes(true); 
     if (attributes.Any(a => a is NotAuthorizeAttribute)) return; 

     // Must login 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
    } 
} 
+15

creo que MVC4 copiado y ahora tenemos [AllowAnonymous] –

+0

Aún útil saber al crear la funcionalidad de validación personalizada en los controladores personalizados :) si – JDandChips

6

Esto es lo que yo haría, similar a la respuesta de Craig con un par de cambios:

1) Crear un atributo común derivan de System.Attribute (sin necesidad de derivar de FilterAttribute ya que no son va a usar cualquier cosa que proporcione FilterAttribute).

Quizás cree una jerarquía de clases de atributos para que pueda realizar pruebas en función de la jerarquía, p.

Attribute 
    AuthorizationAttribute 
     AuthorizationNotRequiredAttribute 
     AuthorizationAdminUserRequiredAttribute 
      AuthorizationSuperUserRequiredAttribute 

2) En su BaseController reemplazar el método OnAuthorization en lugar de la OnActionExecuting método:

protected override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var authorizationAttributes = filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AuthorizationAttribute>(); 
    bool accountRequired = !authorizationAttributes.Any(aa => aa is AuthorizationNotRequiredAttribute); 

Me gusta el enfoque de ser seguro de forma predeterminada: incluso si se olvida de poner un atributo en la acción al menos requerirá que el usuario inicie sesión.

+1

Anulo OnAuthorization (AuthorizationContext filterContext), filterContext no tiene propiedad ActionDescriptor, entonces no tengo idea de cómo encontrar los atributos personalizados de filterContext. – spaceman

+0

¿Puedes confirmar que se trata de ASP.NET MVC 2? Definitivamente hay un ActionDescriptor allí en V2. –

+0

Lo siento, estás en lo cierto, todavía no estoy ejecutando MVC 2. – spaceman

1

Poco tarde para la fiesta, pero terminé creando un atributo de autenticación a nivel de controlador y un atributo de autenticación a nivel de acción y simplemente omitiendo la autenticación de controlador si La acción tiene su propio atributo Auth. Ver código aquí:

https://gist.github.com/948822

26

¿Qué hay de [AllowAnonymous] ??

+0

Esto se creó más tarde, pero ahora es la respuesta correcta. – Technetium

6

Utilice un filtro personalizado como se describe en Securing your ASP.NET MVC 3 Application.

+1

Tenga en cuenta que se desaconsejan las respuestas de solo enlace, las respuestas de desbordamiento de pila deben ser el punto final de una búsqueda de una solución (frente a otra escala más de referencias, que tienden a quedarse obsoletas en el tiempo). –

5

Marque el controlador con [Autorizar]

[Autorizar] clase pública YourController: ApiController

acciones marca que desee público:

[AllowAnonymous]

Cuestiones relacionadas