lunes, 20 de julio de 2015

Forms TimeOut vs sessionState Timeout vs ExecutionTimeout

En este artículo hablaremos de los timeout que se configuran en el web.config en aplicaciones .Net:

  • timeout del tag Form
  • timeout del tag sessionState
  • ExecutionTimeout del tag httpRuntime

Ejemplo de una configuración del web.config:

<system.web>
<authentication mode="Forms">
<forms name="test" loginUrl="~/test.aspx" protection="All" path="/" timeout="40" slidingExpiration="false/true" />
</authentication>

<httpRuntime maxRequestLength="138000" executionTimeout="36000"></httpRuntime>
<sessionState timeout="480"></sessionState>
</system.web>

timeout del tag Form


Por defecto 30 minutos. En el ejemplo está en 40 minutos. Es el tiempo en minutos que el ticket de autenticación es válida (no de la cookie donde esté almacenada el ticket que puede tener otro tiempo o no tener por lo que caduca cuando se cierra el navegador), pasado este tiempo el ticket expira, y al siguiente request te tira al sitio de inicio/login deforma automática. En caso de que la cookies es persistente, el tiempo de timeout es el mismo entre el ticket y la cookie donde está la cookie.

slidingExpiration: Por defecto True en todos los Frameworks, aunque en MSDN hay un error ya que en algunas referencias dice que es False para Framework 2.0 pero en los mismos comentarios MSDN dicen que es True, por ejemplo aquí indica que es True: https://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.slidingexpiration(v=vs.80).aspx y aquí dice que por defecto es False para Framework 2.0: https://msdn.microsoft.com/es-cl/library/1d3t3c61(v=vs.80).aspx. Bueno oficialmente por defecto es True para todos los Frameworks.

En modo false es lo que es conocido como absolute expiration, si el tiempo timeout es 30 (30 min) si un usuario hace un request a las 13 hrs, luego si a las 13:31 hace un nuevo request, este no se procesará y en cambio, le dejará automáticamente en el login.

En modo true, sliding expiration (expiración corrida), la cookie y el ticket se actualizan si el usuario hace un request luego que haya pasado la mitad del tiempo. Por ejemplo si el timeout es 20 y usas sliding expiration en true, y el usuario visita el sitio a las 14 hrs, el usuario recibirá una cookie que expirará a las 14:20 hrs. La cookie se actualiza solo si el usuario visita el sitio luego de las 14:10 hrs.
Si el usuario hace una visita a las 14:12 hrs, la cookie se actualiza y ahora expirará a las 14:32 hrs.
Si el usuario visita el sitio a las 14:09 hrs, la cookie no se actualizará y si se da que el usuario visita el sitio a las 14:21 hrs, el ticket estará expirado y lo dejará en el home de forma automática.

Cuando ticket expira, da el famoso error de Ticket expirado:

Event code: 4005
Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired.


Si no usa el tag authentication en el web.config, por defecto el Framework lo setea así (en Framework 2.0): https://msdn.microsoft.com/en-us/library/532aee0e(v=vs.80).aspx para v2.0, o https://msdn.microsoft.com/en-us/library/532aee0e(v=vs.100).aspx para v4.0.

<authentication mode="Windows">
</authentication> Este modo en el web.config es solo para decirle a .NET como manejar la autenticación no tiene que ver con IIS o el servidor.
De echo, si miras IIS en la sección Autenticación, solo quedará el modo anónimo que es el modo que por defecto trae habilitado. Si quieres modo Windows Authentication y que pida el usuario y clave, debes cambiar en el IIS en la sección Autenticación, y dejar modo Anónimo desactivado y Windows modo activado. Y al ejecutar el sitio pedirá un usuario y clave de Windows.

Si se cambia en el IIS 7 esta configuración, estás afectando a la sección de tu web.config:
system.webServer/security/authentication o applicationHost.config
Y no a <authentication> de <system.web>
En IIS 6 este cambio afecta a la metabase y no a un web.config.

Si no usa el tag forms dentro de authentication en el web.config, por defecto el Framework lo setea así (en Framework 2.0): https://msdn.microsoft.com/es-cl/library/1d3t3c61(v=vs.80).aspx

<forms
name=".ASPXAUTH"
loginUrl="login.aspx"
defaultUrl="default.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
slidingExpiration="true"
cookieless="UseDeviceProfile" domain=""
enableCrossAppRedirects="false">
<credentials passwordFormat="SHA1" />
</forms>

timeout del tag sessionState


Por defecto es 20 minutos. Es el tiempo en minutos que estarán los datos en memoria para una sesión en particular. Por ejemplo, si guardas un objeto en la clase Session se pierde la información a los 480 minutos. El time out se resetea en cada request.
Solo válido si se usa sessionState, es decir que no está como:

<sessionState mode="Off">

Como dato, por defecto el sessionState es InProc:

<sessionState mode="InProc">

Si no usa el tag sessionState en el web.config, por defecto el Framework lo setea así en Framework 2.0: https://msdn.microsoft.com/en-us/library/h6bb9cz9(v=vs.80).aspx

<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI"
sqlCommandTimeout="30"
customProvider=""
cookieless="UseCookies"
cookieName="ASP.NET_SessionId"
timeout="20"
allowCustomSqlDatabase="false"
regenerateExpiredSessionId="true"
partitionResolverType=""
useHostingIdentity="true">
<providers>
<clear />
</providers>
</sessionState>

executionTimeout del tag httpRuntime


Por defecto es 110 segundos. En el ejemplo tiene 36000 (10 hrs). Es el número máximo de segundos que se permite que se ejecute una solicitud antes de que ASP.NET la concluya automáticamente y quede como failed o de el famoso error The request has been aborted. Request timed out.

Este tiempo de espera solo se aplica si el atributo de depuración del elemento

<compilation> está establecido en false. Así que executionTimeout sólo lo toma funciona en modo release, de lo contrario toma el valor por defecto, 110 seg.

Si estas haciendo una aplicación que sube un archivo pesado, por ejemplo de 50 MG, este valor debe ser por ejemplo 3600 (1 hr) para que .NET no la cierre automáticamente.

Tamaño de archivos de subida: maxRequestLength y maxAllowedContentLength

Si quieres permitir que el peso máximo de un archivo a subir sea de 200 MB debes setear dos tag maxRequestLength y maxAllowedContentLength ambos deben ir en el web.config.

El tag maxRequestLength está en KB e indica el tamaño máximo de un archivo soportado por ASP.NET. Si son 200 MB el valor sería 2048000. Por defecto está en 4096 es decir 4 MB.

Si no se usa el tag httpRuntime en el web.config, por defecto el Framework lo setea así en Framework 2.0: https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.80).aspx

<httpRuntime
executionTimeout="110"
maxRequestLength="4096"
requestLengthDiskThreshold="256"
useFullyQualifiedRedirectUrl="false"
minFreeThreads="8"
minLocalRequestFreeThreads="4"
appRequestQueueLimit="5000"
enableKernelOutputCache="true"
enableVersionHeader="true"
requireRootedSaveAsPath="true"
enable="true"
shutdownTimeout="90"
delayNotificationTimeout="5"
waitChangeNotification="0"
maxWaitChangeNotification="0"
requestPriority="Normal"
enableHeaderChecking="true"
sendCacheControlHeader="true"
apartmentThreading="false"
/>

En IIS 7 además se debe setear el atributo maxAllowedContentLength que está en Bytes, indica el tamaño máximo de un archivo a subir soportado por IIS. Aquí los 200 MB serían 2097152000. El valor por defecto es 30000000, lo que equivale a 28.6 MB.
Ojo si que en IIS 7 este valor va en una estructura aparte:

<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2097152000"/>
</requestFiltering>
</security>
</system.webServer>

NOTA: Si estás con IIS 7 o superior, debes setear AMBOS TAG en el mismo valor, sino tomará el menor de ellos como el valor con prioridad.

Referencias


1 comentario: