2010-01-25 17 views
5

Ho un'app MVC che utilizza [Autorizza] per proteggere i bit privati. Quando seleziono l'URL SignOut() mi disconnette, ma se premo il pulsante Indietro sul mio browser, questo va alla pagina sicura e mi consente persino di usare il modulo. L'azione si svolge e poi mostra che sono uscito. Il problema è che esegue l'azione protetta (inserendo una riga nel mio database). Quindi posso usare di nuovo il pulsante Indietro e farlo dappertutto. Se utilizzo il pulsante Indietro dopo aver effettuato il logout e premuto il browser, viene visualizzato che sono disconnesso e mi rifiuta l'accesso alla pagina protetta.Utilizzo del pulsante Indietro del browser dopo SignOut() consente l'accesso alla pagina protetta (ASP.NET MVC)

Mi manca qualcosa di importante? Sembra che potrebbe essere un grosso problema di sicurezza.

public ActionResult LogOff(string ReturnUrl) 
{ 

    FormsAuth.SignOut(); 

    if (!String.IsNullOrEmpty(ReturnUrl)) 
    { 
     return Redirect(ReturnUrl); 
    } 
    else 
    { 

    return RedirectToAction("Index", "Page"); 
    } 
} 
+4

Hai dimenticato di avvolgere [Autorizza] intorno all'azione che accetta il post (sopra [AcceptVerbs (HttpVerbs.Post)]? – Langdon

+0

No, ma quando sono tornato ad avere uno sguardo che aveva in questo modo: \t \t [AcceptVerbs (HttpVerbs.Get)] \t \t [Autorizza (ruoli = "Administrator")] e \t \t [AcceptVerbs (HttpVerbs .Post)] \t \t [Autorizza (ruoli = "Administrator")] Quando ho messo la bandiera Autorizza prima che i AcceptVerbs sia per GET e POST ancora lasciatemi tornare alla forma, ma non mi permetteva di post-it . – mark123

+0

Mi piacerebbe ancora che non mostrasse il modulo sicuro se permette di postare o meno. Questo è un problema strano Utilizzo della decorazione [Autorizza] Non dovrei provare per IsAuthenticated, dovrei? \t \t \t if (! User.Identity.IsAuthenticated) {return RedirectToAction ("LogOn", "Account");} – mark123

risposta

5

Penso che il problema sia che il browser memorizza nella cache la pagina. Ecco perché non ricarica la pagina dopo aver fatto clic sul pulsante Indietro. Se specifichi nelle intestazioni che la pagina non debba essere memorizzata nella cache, dovrebbe ricaricare la pagina dopo aver premuto il pulsante Indietro. E poi l'utente viene rifiutato.

Tuttavia, per farlo funzionare potrebbe essere difficile in alcuni casi. Vedere questo Caching Tutorial per ulteriori informazioni.

1

Si sta utilizzando qualche informazione di sessione? FormsAuth.SignOut() interessa solo le nuove istanze di una pagina. Quando sei tornato, sei stato autorizzato a stare lì (in precedenza). Il PostBack è consentito a meno che tu non abbia il controllo del codice per il cookie/sessione/autenticità della richiesta. Ignora anche il global.asax perché ViewState è già stato generato.

È possibile aggiungere un'istruzione di interruzione della sessione o fornire alcuni controlli dell'autorizzazione extra nelle classi di base per assicurarsi che un utente sia effettivamente autorizzato a trovarsi dove si trova, QUANDO lo sono.

In alternativa, è possibile disattivare la memorizzazione nella cache della pagina che dovrebbe rendere il pulsante Indietro abbastanza inutile (fornirà la pagina scaduta di default). Ciò creerà delle stranezze per gli utenti che si affidano al pulsante Indietro, ma contribuirà a garantire la sicurezza della pagina, poiché in primo luogo imporrà un "re-rendering" della pagina.

+0

Sta usando MVC, quindi i postback e i viewstate non dovrebbero essere un problema. L'uso di 'Session.Abandon()' sul controllo di logout è comunque una buona idea. –

+0

In questo caso non sto utilizzando le informazioni sulla sessione. – mark123

3

La compensazione della sessione potrebbe essere d'aiuto. ecco il mio metodo di disconnessione:

public ActionResult Signout() 
    { 
     Session.Clear(); 
     FormsAuthentication.SignOut(); 
     return RedirectToAction("Index", "Home"); 
    } 
1

questo è quello di rispondere in ritardo, ma spero di aiutare qualcuno in un momento in Global.asax aggiungere questo metodo

protected void Application_BeginRequest() 
{ 
    Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1)); 
    Response.Cache.SetNoStore(); 
} 

e poi, dopo il ricorso principale aggiungere questo controllo

if (Request.IsAuthenticated) 
{ 
    // do something 
} 
else 
{ 
    return RedirectToAction("LoginPage", "ControllerName"); 
} 

(azione principale significa qualsiasi azione [httpget]) e funzionerà molto spero di aiutare

Problemi correlati