2013-04-14 31 views
5

Sto usando l'inizializzatore DropCreateDatabaseAlways così il mio database viene distrutto ogni volta che avvio l'applicazione (almeno lo spero). La cosa divertente è che mi vedo ancora come connesso. Ricevo l'attributo Authorize e posso fare cose pericolose. Ciò è probabilmente dovuto ai cookie residui dei test precedenti.ASP.NET MVC autentica e autorizza utenti inesistenti

La parte di registrazione/accesso della mia app è il modello di applicazione Internet MVC 4 non toccato. Non dovrebbe ASP.NET verificare i valori del cookie rispetto agli utenti salvati nel DB? WebSecurity.IsAuthenticated restituisce true e WebSecurity.CurrentUserName restituisce il nome. L'unica cosa che funziona come previsto è WebSecurity.CurrentUserId che restituisce -1. Sono un principiante quindi posso solo supporre che questo sia perché UserId non è memorizzato nel cookie e deve essere recuperato dal database.

Ho ragione? In tal caso, significa che dovrei sempre usare WebSecurity.CurrentUserId per determinare se un utente ha effettuato l'accesso? WebSecurity.IsAuthenticated e User.Identity.IsAuthenticated sembrano abbastanza inutili in quel caso. Posso cancellare l'account di un utente e lui o lei rimane inalterato. Cosa dovrebbe essere fatto in modo diverso se sbaglio?

+0

Devo chiedere. Importa davvero? In produzione, quanto spesso butti via il database? Mai? Quindi qual è il problema? Se sei preoccupato, non rendere persistente il cookie (rimuovi le caselle di controllo che mantengono l'accesso e imposta false per cookie persistenti). Sì, puoi eliminarli e se sono attualmente connessi possono comunque avere accesso, ma non appena chiudono il browser non possono accedere nuovamente. –

risposta

1

Ci sarà una piccola finestra in cui se un utente viene cancellato e sono ancora loggati che possono ancora accedere al sito. Poiché la maggior parte delle azioni richiede un ID utente valido, è sufficiente lanciare un'escrizione e disconnettere l'utente.

Normalmente il database non viene spazzato via su ogni build, quindi suppongo che questo non sia un caso d'uso per cui è stato codificato SimpleMembership. Ovviamente puoi verificarlo. Prenderò un'altra ipotesi che non si sta chiudendo il browser quando si ricostruisce il sito e si distribuisce il nuovo database. In uno scenario del mondo reale queste cose semplicemente non accadono. Il database non viene mai spazzato via e l'ID utente non viene mai perso.

Generalmente dopo aver effettuato l'accesso, l'utente non viene autenticato in un secondo momento (a meno che non si sia disconnesso o la sessione sia scaduta). Questo è il punto di accesso. Il cookie di autenticazione è un'indicazione che l'autenticazione è avvenuta e ha avuto successo. L'assunto futuro è che l'utente abbia accesso al tuo sito e non sia nuovamente autenticato.

+0

Mi sembra un errore di sicurezza che l'iscrizione (Semplice) non esegue una query nel database e utilizza ciecamente il nome utente estratto dal cookie di autenticazione. Che cosa va bene se l'utente potrebbe essere già stato cancellato e poiché ho comunque bisogno di id utente? –

+1

@MattRicks È un presupposto che una volta che sei stato autenticato l'account sia valido. In tutti i sistemi su cui ho lavorato non ho mai visto un caso in cui l'utente abbia effettuato l'accesso quando un account è stato cancellato. Per non dire che non può accadere, è un caso limite. Perché è una brutta cosa usare l'id utente dal cookie auth? Il cookie auth è crittografato specifico per quella macchina. Si fida del cookie, perché imposta il cookie. –

+2

Beh, penso che il metodo IsAuthenticated dovrebbe funzionare così: 1. verificare i valori del cookie 2. interrogare il DB per l'ID utente 3. restituire se l'utente ha il cookie auth AND. Sembra che io sia l'unico ad avere problemi con la versione corrente. :) –

0

In caso normale aggiungendo Session.Abandon(); To al tuo LogOff azione AccountController avrebbe fatto il lavoro della sessione di compensazione:

public ActionResult LogOff() 
{ 
    FormsAuthentication.SignOut(); 
    Session.Abandon(); 

    return RedirectToAction("Index", "Home"); 
} 

Quindi penso che si può provare ad aggiungere Session.Abandon(); nel codice di inizializzazione, in cui si utilizza DropCreateDatabaseAlways per cancellare la sessione ogni volta.

1

Se si desidera verificare in modo attendibile se un utente non è stato cancellato, è sufficiente che lo abbia il per consultare il database.

Nota che gli utenti e gli amministratori lavorano contemporaneamente. Ciò significa che un utente può essere cancellato solo un secondo dopo che è stato autenticato. Un cookie può essere anche vecchio di uno o due secondi (!) E l'utente potrebbe probabilmente essere stato appena cancellato.

In uno scenario molto pessimistico, un utente digita un nome utente e una password validi e accede con successo e ottiene il messaggio "mi dispiace, il tuo account è stato eliminato" una sola richiesta in seguito (perché l'account è stato appena cancellato).

0
  • Il biglietto orario di emissione è di solito criptato all'interno del cookie di autenticazione, allora si può utilizzare per richiedere nuovamente l'autenticazione di aree sensibili (posta in arrivo/fatturazione, ecc) se è trascorso più di X volta dal login.

  • Se ti ostini a invalidare tutti i biglietti auth attuali sulle modifiche alle applicazioni (ad esempio database di/configurazione) è possibile modificare questa impostazione nel vostro web.config:

    <machineKey validationKey="..." decryptionKey="" /> 
    
1

Finché la sessione di autenticazione rimane aperta (es. browser ora chiuso), il cookie di sessione rimane attivo e MVC presume che l'utente sia ancora valido.

Rimuovere il cookie utilizzando FormsAuthentication.LogOff() se l'utente è autenticato (User.Identity.IsAuthenticated == true) e non esiste un utente valido in UserTable (WebSecurity.CurrentUserId == -1).

1

Ho avuto lo stesso problema, ma l'ho risolto specificando i ruoli richiesti nell'attributo Autorizza. Non appena lo fai, inizia ad arrivare al database e fallisce con l'errore "L'utente non esiste", che è quello che vuoi.

[Authorize(Roles = "Customer")] 
public class DashboardController : Controller 
Problemi correlati