2011-08-17 20 views

Respuesta

15

usted puede hacer esto por 3 maneras:

  1. Crear un filtro a los actos y aplicarlo programación de un código en OnActionExecuting (antes ha ejecutado la acción), http://www.asp.net/mvc/tutorials/understanding-action-filters-cs

  2. Crear una base de clase (heredando de la clase Controller) y hacer que sus controladores hereden de este. En esta clase, podría sobreescribir un método llamado OnActionExecuting, como el filtro.

  3. No utilizar para la autenticación de sesión, puede utilizar la autenticación de formularios y que sea sencillo de usar, mira esto: http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx

En mi opinión, la solución 3 es mejor que otra. ¡Espero que te sirva!

+6

La solución 3 es incorrecta. Al usar la autenticación de formularios, el usuario aún puede ser autenticado a través de una cookie, pero tiene una nueva sesión. Si su controlador no detecta esto, puede tener excepciones al intentar acceder al objeto Session que no ha sido configurado por la página de inicio de sesión. –

+0

La solución 1 es técnicamente incorrecta. Aunque es un filtro, un uso se deriva de 'AuthorizeAttribute' y' IAuthorizationFilter' y luego anula 'OnAuthorization' y/o' AuthorizeCore' según la situación. Este es el caso desde MVC 2. –

+0

@ErikPhilips, podría sugerir un enlace/ejemplo para aclarar. Gracias. –

7

porque es posible copiar la cookie de seguridad de la Autenticación de formularios usarla para simular un usuario registrado. Uso el siguiente atributo para vincular la autenticación a la vigencia de la sesión actual.

Para que el atributo funcione, debe establecer la sesión ["user"] = MyUser al iniciar sesión y llamar a session.abandom() al cerrar la sesión. No sé si la redirección funciona con llamadas ajax; eso es algo que debes probar.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
public class CheckUserSessionAttribute : ActionFilterAttribute 
{ 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     HttpSessionStateBase session = filterContext.HttpContext.Session; 
     var user = session["User"]; 

     if (((user == null) && (!session.IsNewSession)) || (session.IsNewSession)) 
     { 
      //send them off to the login page 
      var url = new UrlHelper(filterContext.RequestContext); 
      var loginUrl = url.Content("~/Account/LogOff"); 
      session.RemoveAll(); 
      session.Clear(); 
      session.Abandon(); 
      filterContext.HttpContext.Response.Redirect(loginUrl, true); 
     } 
    } 
} 
+0

El redireccionamiento no parece funcionar para mí. Tengo un sitio móvil MVC que parece significar que todo usa AJAX. No estoy seguro de cómo obtener el redireccionamiento para trabajar. –

+0

si aplico este atributo a una clase, ¿cómo puedo escribir un atributo invertido para aplicarlo a la acción? UncheckUserSessionAttribute por ejemplo – Wachburn

+0

Creo que esto no es compatible con el framework MVC. Por lo que sé, evaluará todos los atributos de filtro. No puedo imaginar una forma de cómo resolver tu problema. Entonces debes aplicarlo a todos los métodos en tu clase. – Michael

3

Esto responde se basa en gran medida en Michaels, excepto que funciona ;-)

lo cambié a tomar una delegue para verificar si la sesión ha finalizado para que pueda funcionar en diferentes aplicaciones que pueden tener diferentes formas de determinar esto y también la página de inicio de sesión puede ser diferente en otras aplicaciones. En el Global.asax.cs Application_Start() el código que tengo en mi aplicación es

CheckUserSessionAttribute.CheckSessionAlive = session => (session.GetUser() != null); 
CheckUserSessionAttribute.LoginUrl = "~/Account/Login"; 

A continuación, la clase de atributo es el siguiente

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public class CheckUserSessionAttribute : ActionFilterAttribute 
    { 
     public static String LoginUrl { get; set; } 
     public delegate bool CheckSessionDelegate(HttpSessionStateBase session); 

     public static CheckSessionDelegate CheckSessionAlive; 

     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 

      HttpSessionStateBase session = filterContext.HttpContext.Session; 
      if ((CheckSessionAlive == null) || (CheckSessionAlive(session))) 
        return; 


      //send them off to the login page 
      var url = new UrlHelper(filterContext.RequestContext); 
      var loginUrl = url.Content(LoginUrl); 
      session.RemoveAll(); 
      session.Clear(); 
      session.Abandon(); 

      filterContext.HttpContext.Response.StatusCode = 403; 
      filterContext.HttpContext.Response.Redirect(loginUrl, false); 
      filterContext.Result = new EmptyResult(); 

     } 
    } 

Desde su controlador sólo tiene que añadir la [CheckUserSession] atribuir anteriormente la clase o las acciones individuales.

Cuestiones relacionadas