2009-09-17 7 views
12

Estoy usando ActionFilterAttribute para realizar una lógica de autenticación personalizada. El atributo solo se usará en una clase de controlador derivado que contenga mi lógica de autenticación.ActionFilterAttribute: se aplica a acciones de un tipo de controlador específico

Aquí está mi controlador, derivado de mi clase de controlador personalizado, y un atributo de la muestra:

public class MyController : CustomControllerBase 
{ 

    [CustomAuthorize(UserType = UserTypes.Admin)] 
    public ActionResult DoSomethingSecure() 
    { 
     return View(); 
    } 

} 

He aquí un ejemplo de mi ActionFilterAttribute:

public class CustomAuthorizeAttribute : ActionFilterAttribute 
{ 
    public MyUserTypes UserType { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     myUser user = ((CustomControllerBase)filterContext.Controller).User; 

     if(!user.isAuthenticated) 
     { 
     filterContext.RequestContext.HttpContext.Response.StatusCode = 401; 
     } 
    } 
} 

funciona muy bien.

Aquí está la pregunta: ¿Puedo exigir que este atributo SÓLO se use en Acciones en mi tipo de controlador personalizado?

+1

Su atributo está roto porque no hereda de AuthroizeAttribute y, por lo tanto, no se garantiza que se ejecute cuando la acción se almacena en caché. Consulte http://blogs.teamb.com/craigstuntz/2009/09/09/38390/ para conocer las soluciones que funcionan con el almacenamiento en caché. –

+0

¿Por qué el resultado de la acción se almacenará en caché? –

+0

Se almacenaría en caché porque alguien le dijo que se almacenara en caché. Imagine que alguien pone el atributo Cache en una clase principal, sin darse cuenta del atributo roto en el subtipo. Es una idea mucho mejor usar un atributo que no es fundamentalmente incompatible con el almacenamiento en caché de ASP.NET/MVC. Vea el enlace de arriba para las opciones. –

Respuesta

14

Puede poner el ActionFilter en la clase misma. Todas las acciones en la clase realizarán el ActionFilter.

[CustomAuthorize] 
public class AuthorizedControllerBase : CustomControllerBase 
{ 
} 

public class OpenAccessControllerBase : CustomControllerBase 
{ 
} 

public class MyRealController : AuthorizedControllerBase 
{ 
    // GET: /myrealcontroller/index 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 
+0

Voy por la ruta de definir el ActionFilter dentro de la clase (por lo que no está disponible en otras clases). Es bueno saber que el atributo se puede definir en TODOS los resultados de acción en un controlador. –

7

Basado en los comentarios y las limitaciones de mi sistema, tomé un enfoque híbrido. Básicamente, si la solicitud se envía a través de una ruta en caché o el "Usuario" no está configurado por algún motivo, la autenticación falla de la manera adecuada.

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    private MyUser User { get; set; } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //Lazy loads the user in the controller. 
    User = ((MyControllerBase)filterContext.Controller).User; 

    base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
    bool isAuthorized = false; 
    string retLink = httpContext.Request.Url.AbsolutePath; 

    if(User != null) 
    { 
     isAuthorized = User.IsValidated; 
    } 

    if (!isAuthorized) 
    { 
     //If the current request is coming in via an AJAX call, 
     //simply return a basic 401 status code, otherwise, 
     //redirect to the login page. 
     if (httpContext.Request.IsAjaxRequest()) 
     { 
     httpContext.Response.StatusCode = 401; 
     } 
     else 
     { 
     httpContext.Response.Redirect("/login?retlink=" + retLink); 
     } 
    } 

    return isAuthorized; 
    } 
} 
+0

Si está redireccionando en cualquier caso "isAuthorized = false", ¿por qué no simplemente devuelve true al final? – Alex

+0

En el caso del flujo de IsAjaxRequest, no se redirige al usuario, por lo que el método aún debe devolverse. –

+0

+1 para usar AuthorizeAttribute en lugar de ActionFilterAttribute. Resuelve el problema de que la acción del controlador que tiene el atributo CustomAuthotize se ejecuta incluso si no estamos conectados, lo que puede ocasionar otros problemas. –

Cuestiones relacionadas