2011-08-17 12 views

risposta

15

si potrebbe fare questo da 3 modi:

  1. Creare un filtro per le vostre azioni e applicarlo programmazione di un codice OnActionExecuting (prima stata eseguita l'azione), http://www.asp.net/mvc/tutorials/understanding-action-filters-cs

  2. creare una base classe (che eredita dalla classe Controller) e che i controller ereditano da questa. In questa classe potresti sovrascrivere un metodo chiamato OnActionExecuting, come il filtro.

  3. Non utilizzare sessione per l'autenticazione, è possibile utilizzare l'autenticazione Forms e mantenerlo semplice da usare, ti segnalo: http://weblogs.asp.net/fredriknormen/archive/2008/02/07/asp-net-mvc-framework-using-forms-authentication.aspx

A mio parere, la soluzione 3 è meglio di altri. Spero che funzioni per te!

+6

La soluzione 3 è errata. Utilizzando l'autenticazione basata su moduli, l'utente può ancora essere autenticato tramite un cookie ma avere una sessione completamente nuova. Se il tuo controller non lo rileva, puoi avere eccezioni nel tentativo di accedere all'oggetto Session che non è stato configurato dalla pagina di accesso. –

+0

La soluzione 1 è tecnicamente errata. Sebbene sia un filtro, un uso deriva da "AuthorizeAttribute" e "IAuthorizationFilter" e quindi sovrascrive "OnAuthorization" e/o "AuthorizeCore" a seconda della situazione. Questo è il caso fino a MVC 2. –

+0

@ErikPhilips, potresti suggerire un link/esempio per chiarire ulteriormente. Grazie. –

7

perché è possibile copiare il cookie di sicurezza dei moduli-Autenticazione usarlo per simulare un utente registrato Io uso il seguente attributo per associare l'autenticazione alla durata corrente della sessione.

Per far funzionare l'attributo è necessario impostare la sessione ["utente"] = MyUser all'accesso e chiamare session.abandom() al logout. Non so se il reindirizzamento funziona con chiamate ajax - è qualcosa che devi provare.

[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

Il reindirizzamento non sembra funzionare per me. Ho un sito mobile MVC che sembra significare che tutto utilizza AJAX. Non sei sicuro di come il reindirizzamento funzioni. –

+0

se applico questo attributo ad una classe, come posso scrivere un attributo invert per applicarlo all'azione? UncheckUserSessionAttribute ad esempio – Wachburn

+0

Penso che questo non sia supportato dal framework MVC. Per quanto ne so valuterà tutti gli attributi del filtro. Non riesco ad immaginare un modo per risolvere il tuo problema. Quindi devi applicarlo a tutti i metodi della tua classe. – Michael

3

Questo risponde è fortemente basato su Michaels, tranne che funziona ;-)

ho cambiato di prendere una delegare per verificare se la sessione è terminata in modo che possa funzionare in diverse app che potrebbero avere diversi modi per determinarlo e anche la pagina di accesso potrebbe essere diversa in altre app. Nel Global.asax.cs Application_Start() il codice che ho nel mio app è

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

Poi la classe di attributo è il seguente

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

     } 
    } 

dal controller basta aggiungere il [CheckUserSession] attributo sopra la classe o le singole azioni.

Problemi correlati