2010-02-15 9 views
5

IL CODICE:Perché/quando le scritture di sessione sono vulnerabili alla terminazione del thread?

Session["foo"] = "bar"; 
Response.Redirect("foo.aspx"); 

IL PROBLEMA:

Quando foo.aspx legge "foo" dalla sessione, non è lì. La sessione è, ma non c'è alcun valore per "pippo".

L'ho osservato a intermittenza nel nostro ambiente di produzione. Ma non intendo qui per chiedere a question about Response.Redirect().

LA SPIEGAZIONE:

Bertrand Le Roy spiega (il grassetto è mio):

Ora, che cosa Redirect fa è quello di inviare un'intestazione speciale al cliente in modo che si chiede al server per una diversa pagina rispetto a quella che stava aspettando. Lato server, dopo aver inviato questa intestazione , Redirect termina la risposta. Questa è una cosa molto violenta da fare. Response.End arresta effettivamente l'esecuzione della pagina ovunque sia utilizzando una ThreadAbortException. Quello che accade davvero qui è che il token di sessione si perde nella battaglia.

Il mio takeaway è che Response.Redirect() può essere pesante con i thread finali. E questo può minacciare la mia sessione di scrittura se si verificano troppo vicino a quella pesantezza.

LA DOMANDA:

Che dire di ASP.NET gestione delle sessioni rende così vulnerabili a questo? Il() Linea Response.Redirect di codice non inizia la sua esecuzione fino a quando la linea di sessione di scrittura è "finito" - come può essere una minaccia per la mia scrittura sessione?

E la scrittura di sessione non "finire" prima della riga successiva di codice viene eseguito? Ci sono altri scenari in cui le scritture di sessione sono similmente (come se non si siano mai verificate) perse?

risposta

1

Dopo aver provato diverse alternative (Response.Redirect (..., false), Server.Transfer() e altre "soluzioni" che non riesco a ricordare), abbiamo trovato solo una risposta affidabile a questo problema .

Lo spostamento dello stato di sessione da InProc a SqlServer ha sradicato efficacemente questo comportamento dai nostri sistemi, lasciando Response.Redirect (...) completamente affidabile. Se ulteriori test mostreranno il contrario, riferirò qui, ma dico, per far sì che questo si fermi nel tuo ambiente: sposta lo stato della sessione in SqlServer (o è "fuori da InProc" abbastanza buono? Non sono sicuro).

2

io non sono abbastanza familiarità con la struttura interna di scrittura sessione, ma immagino che ha alcune complessità, in quanto si basa sulla traduzione dei cookie di sessione del browser in un server di identificazione. Inoltre, ThreadAbortExceptions do have special considerations in fase di esecuzione, che può giocare in qui, non sono sicuro.

In ogni caso, Response.Redirect() ha un sovraccarico che accetta un parametro booleano che consente di specificare se si desidera terminare il thread o meno.

Response.Redirect(string url, bool endResponse); 

Se lo si chiama con endResponse impostato su "false", sarà con grazia finire, piuttosto che chiamare Thread.Abort() internamente. Tuttavia, questo significa che eseguirà anche qualsiasi codice rimasto nel ciclo di vita della pagina prima di finire.

Un buon compromesso è chiamare Response.Redirect(url, false) seguito da Application.CompleteRequest(). Ciò consentirà al tuo reindirizzamento di accadere, ma anche di chiudere con grazia il contesto di esecuzione corrente con una quantità minima di ulteriore elaborazione del ciclo di vita.

0

Il riciclo del pool di applicazioni può causare l'interruzione della sessione. È possibile configurare il pool di app da riciclare a orari prestabiliti (consigliato, di notte o durante periodi di utilizzo ridotto) o aumentare il periodo di timeout del riciclo del pool di app.

Problemi correlati