2012-01-26 24 views
6

C'è un modo per scoprire se un ID di sessione è valido all'interno di un contesto di richiesta esistente? In questo caso, se mi viene dato un ID di sessione e sono attualmente in un'altra sessione avviata da una richiesta HTTP e sono su una pagina o in qualche classe, posso convalidare quell'ID di sessione, se è valido e attualmente esiste e non è stato abbandonato?In ASP.Net, posso scoprire se esiste un'altra sessione o è valida per un ID di sessione?

La ragione di questo è, abbiamo bisogno di bloccare il processo di login utente sulla pagina per il progetto su cui sto lavorando in modo che qualsiasi utente può essere registrato solo in una volta. Il mio pensiero su questo è stato quello di aggiungere una colonna id di sessione alla tabella utente, se è nullo, sono disconnessi ed è impostata quando si collegano e si cancellano quando si disconnettono o su Session_End in global.asax. Tuttavia, se per qualche motivo una sessione viene abbandonata senza averlo eliminato, devo essere in grado di collegarli di nuovo, e in quel caso ogni volta che accedono e trova un ID di sessione in quella colonna, penso che in qualche modo dovrebbe controllare per vedere se tale sessione Id è attivo e valido, se non, sarà ripristinato al loro nuovo ID di sessione e consentire loro di log-in.

Grazie

+0

Avete bisogno di mantenere la loro sessione di sempre? Ciò significa che ASP .NET finirà per abbandonare le sessioni scadute. Ma dal punto di vista dell'utente lo stato dell'applicazione dovrebbe rimanere sempre lo stesso? – Yuck

+0

Non ce l'abbiamo, abbiamo un timeout di 30 minuti che richiede all'utente di eseguire di nuovo il login. Non stiamo utilizzando alcuna autenticazione basata su cookie, solo la sessione attiva e l'archiviazione dell'oggetto utente al suo interno. Quando la sessione scade, vengono "disconnessi" e devono effettuare nuovamente il login. –

risposta

0

non esiste un modo diretto di convalidare SessionId. Opzioni:

  • È possibile implementare il proprio fornitore di stato della sessione (o forse responsabile ID sarebbe sufficiente) per esporre l'accesso a tali informazioni (http://msdn.microsoft.com/en-us/library/aa479024.aspx).
  • Basta provare a imbrogliare impostando il cookie ID di sessione in base all'ID che si ritiene che l'utente corrente debba avere e rieseguire il rendering della pagina. Una seconda richiesta sarete in grado di vedere se quell'ID corrisponde allo stato valido e ri-effettuare il login se necessario.

Nota: non utilizzerei l'id di sessione a tale scopo poiché farai affidamento sui dettagli di implementazione. Forse il semplice rifiuto di sessioni che non sembrano più recenti per questo utente funzionerebbe. Avere la proprietà "nome della sessione corrente" salvata in Session["someName"] e nel DB utente dovrebbe essere sufficiente per rifiutare il rendering delle sessioni precedenti.

2

è necessario memorizzare le sessioni nel database per trovare prima.
Vedi altro in HOW TO: Configure SQL Server to Store ASP.NET Session State

+0

Il commento sopra ha un pessimo inglese, ma l'idea giusta. Se hai usato il server SQL per lo stato della sessione, credo che memorizzi l'ID di sessione come una colonna. Potresti controllare quello. – Rocklan

1

L'unico modo che posso pensare è quello di fare come dice Neperz e memorizzare le sessioni in un database utilizzando il provider SQLServer sessione, significa che è possibile utilizzare una query SQL per vedere cosa è disponibile.

ma ci sono alcune avvertenze da considerare:

  1. credo che l'ID di sessione memorizzato nella tabella del database sessione non è esattamente lo stesso ID di sessione è possibile accedere da codice. Non riesco a ricordare esattamente dove ho letto questo, ma penso di aver avuto questo problema mentre stavo facendo qualcosa di simile per monitorare tutte le sessioni attive.
  2. Il Session_End evento globale non sarà mai il fuoco se si utilizza il provider SQLServer sessione.
  3. A meno che non si utilizza in modo esplicito Session.Abandon() nel codice per terminare una sessione (ad esempio, quando un utente si disconnette), le sessioni possono rimanere in giro fino a quando un processo di SQL Agente pulisce tutte le sessioni scadute. Ciò significa che se qualcuno ha appena chiuso la finestra del browser, la loro sessione sembrerebbe ancora "attiva", il che potrebbe complicare la tua implementazione.
1

Un'altra opzione che avete/aveva :-) sarebbe quella di utilizzare WeakReferences:

  • un Dictionary<youruseridtype,WeakReference> viene conservato a livello di applicazione come applicazione [ "mySessionDictionnary"]
  • all'avvio di una sessione, è memorizzare userid e WeakReference sull'oggetto Session stesso nel dizionario
  • quando un utente desidera effettuare l'accesso, si accede al dizionario per il proprio ID. Se esiste un WeakReference non vuoto per un oggetto Session, è possibile Abandon() questo oggetto Session esistente, assicurandosi che non ci sia più di una sessione attiva per utente.

Il WeakReference garantisce che non si verifichino perdite di memoria.

NB: questo funziona solo con la gestione delle sessioni inProc. Dato che Dictionnary non sopravviverebbe al riavvio dell'applicazione, dovrebbe essere lo stesso per le sessioni.

Speranza che hai già trovato la risposta giusta al vostro problema ;-)