viernes, 26 de junio de 2015

¿El ViewState de ASP.NET está poniendo lenta tu página?

Un desafío muy común entre desarrolladores y diseñadores web es crear sitios web que sean interactivos, con buen diseño, responsivos y que carguen rápido, de esta forma mantener al usuario feliz. ASP.NET es una plataforma de desarrollo fantástica, pero como desarrolladores podemos tener problemas de performance causados por el viewstate, sobretodo si trabajamos con .Net Framework 2.0.

¿Que es el viewstate?

El Viewstate es una técnica usada por ASP.NET para manejar los estados de los web forms a través de los postbacks. Un postback es un intercambio de datos de un formulario con el server. El viewstate de una página es, por defecto, almacenado en un campo oculto del formulario de la página web llamado __VIEWSTATE y es de donde pueden surgir los problemas:

< input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTEwNzcyMTI4ODkPZBYCAgMPZBYGAgMPD2QWAh4Dc3JjBRVDb250cm9sL0dldEltYWdlLmFzaHhkAgcPDxYCHgRUZXh0BSJNw7NkdWxvIENhcnRlcmEgLSBNZWRpc3luIENvbG9tYmlhZGQCCQ8PFgIfAQUIQ3RyMDAxaXdkZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAgULaWJ0bkFjZXB0YXIFC2lidG5MaW1waWFyA3FR8EtTrIE9o6Xpg7IeJ9eVFzg=" >

¿Porque es un problema?

El volumen de datos almacenado en este campo oculto puede ser muy largo. Esto implica que se incrementa la carga de la página y ya que todo el contenido del campo oculto debe ser intercambiado durante un postback, se puede ver un notorio aumento del tiempo de completitud del request HTTP.

Los desarrolladores web actualmente están dispuestos a pulir el sitio, dejándolo operativo para conexiones lentas, mantenido el user-friendly, todo esto para minimizar el tamaño de datos almacenado e intercambiado en el viewstate. A esto hay que sumarle que Google confirmó que el tiempo de carga de un sitio web es uno de los factores que influye en como aparecen en el SERP, lo que hace que el desarrollador web se incentive a que el sitio cargue rápido. Quizá lo que más importa, desde la perspectiva de SEO, es que los datos de un viewstate en general preceden al contenido de una página importante en el orden de origen y puede inflar significativamente el código de la página.

¿Qué podemos hacer?

1) En general, un sitio no debería basarse en el viewstate. Esto debe ser decidido en un comienzo ya que desactivarlo una vez el sitio está desarrollado puede traer resultados inesperados (y el sitio dejará de funcionar).

2) Considera el uso de otros controles de estado de formulario, por ejemplo session state, application state, manualmente poblar/restaurar campos ocultos, cookies. El ASP.NET Cache puede ser usado para almacenar datos o repoblar controles para prevenir vueltas innecesarias a la base de datos.

3) Si usas controles de servidor intenta restringir el uso de tipos simples, por ejemplo repetidores en vez data grid/view.

4) El Viewstate puede ser eliminado de una página web cuando no se usan formularios o controles de servidor (con el atributo runat="server"), sin embargo el desarrollador es el responsable de escribir el código para hacer los post de los formularios manualmente al estilo antiguo (Request.Form, por ejemplo http://www.w3schools.com/asp/asp_inputforms.asp).

5) Viewstate puede ser desactivado de una aplicación, página o control usando el tag enableViewState="false". Si desactivas el viewstate de toda la aplicación se mantendrá "cierto" viewstate en todas las páginas (como el viewstate es usado para manejar que controles requieren postback). Esta es la forma de comunicación entre ASP.NET Web Forms y el modelo de postback.

6) En la mayoría de los casos, basta con desactivar el viewstate de un control y asegurarse que están llegando todos los datos en cada postback, proveen una reducción suficiente en el tamaño del viewstate. Cuando se hace esto, se debe repoblar los controles en el evento Init, no en evento Load. Hacer el data binding durante el evento Load tiene el riesgo de sobreescribir los valores los cuales serán restaurados desde los Formularios durante el evento Load.

7) Puedes ver que páginas están usando de forma intensa el viewstate con una muy buena herramienta llamada ASP.NET View State Helper: http://www.binaryfortress.com/aspnet-viewstate-helper.
Explicación de las columnas en el herramienta:

  • Page Size: bytes que pesa la página de la columna Page URL.
  • View State Size: tamaño en bytes que pesa el viewstate y la cantidad de chunks si está dividido
  • View State %: del total de la página, cuanto % es del View State
  • View State %: del total de la página, cuanto % es del View State. Si es muy alto coloca amarillo.
  • Markup Size: tamaño en bytes del HTNL del código de la página que no es texto visible.
  • Markup %: del total del tamaño de la página, cuando corresponde a código no visible. El color amarillo por lo que leí acá el amarillo en esta columna significa que el valor está sobre un 90% o bajo un 10%.

8) Los ViewState muy grandes pueden ser fragmentada (chunk) en un número más pequeño de campos usando la opción maxPageStateFieldlength del web.config file. Esta opción permite setear la cantidad máxima en bytes. Por defecto es -1, por lo que no está dividido, pero si colocamos un entero, se dividirá hasta alcanzar ese valor. Por ejemplo si ponemos 40 se dividirá en trozos muy pequeños, pero si usamos 500 serán más grandes. Por ejemplo, usaremos chunks de 256 bytes por ejemplo quedaría así:

Si tenemos un ViewState:

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTk2Njk3OTQxNg9kFgICAw9kFgICCQ88KwANAGQYAQUJR3JpZFZpZXcxD2dk4sjERFfnDXV/hMFGAL10HQUnZbk=" />

Si cambiamos maxPageStateFieldlength en el web.config para dejar 256 bytes:

<system.web>
...
<pages maxPageStateFieldLength="256">
...
</system.web>

Así se verá el ViewState:

<input type="hidden" name="__VIEWSTATEFIELDCOUNT" id="__VIEWSTATEFIELDCOUNT" value="3" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTk2Njk3OTQxNg9kFgICAw9kFgICCQ88" />
<input type="hidden" name="__VIEWSTATE1" id="__VIEWSTATE1" value="KwANAGQYAQUJR3JpZFZpZXcxD2dk4sjERFfnDXV/" />
<input type="hidden" name="__VIEWSTATE2" id="__VIEWSTATE2" value="hMFGAL10HQUnZbk=" />

En la herramienta ASP.NET ViewState Helper así se ven los chunks:


9) El modelo ASP.NET MVC no usa ViewState. Considera usar MVC para la capa interfaz de tu aplicación y mantener lo que tienes del modelo de Web Form para el negocio o acceso a datos. MVC lo puedes usar con el Framework .NET 3.5 en adelante.

10) ASP.NET 4.0 Web Forms incluye la propiedad ViewStateMode, el cual permite desactivar el viewstate por defecto y activarlo solo a los controles que lo requieran.

Esperemos que estas sugerencias ayuden a los desarrolladores que luchan por bajar unos pocos kilobytes de sus páginas .NET.

No confundir errores de ViewState con errores de programación

A veces, sucede que se le puede atribuir al ViewState, errores que no son de este, pero si de programación JavaScript o de código ASPX (VB.NET o C#). Recomiendo validar el ViewState y ver que si sube pero luego se mantiene, el problema puede ser otro. En mi caso subía hasta 12000 bytes si lo analizaba con ASP.NET ViewState Helper, pero pasado ciertos request se mantenía en ese valor.
Si sucede esto, el problema puede no ser el ViewState, sino un código erróneo en la aplicación, en mi caso era un error de código JavaScript y la forma de detectarlo fue usando las herramientas de Internet Explorer o Chrome, ambos con F12, usando el Generador de Perfiles en IE o Profiles en Chrome.

En IE aparece un árbol de llamadas y allí se ven los tiempos y el número de veces que se ejecuta cierta función del JavaScript. En mi caso, aparecía una función que se llamaba 131 mil veces en cierto momento. La solución fue comentar un línea de código.

Generador de Perfiles de IE 8.

Generador de Perfiles de IE 11.

En Chrome se debe escoger el tipo de Perfil y presionar START. Luego se verán las llamadas y tiempos de las funciones JavaScript. Con Control + F puedes buscar un nombre de función, por si tienes alguna pista de algo que podría andar lento.





Referencias


Traducción con aclaraciones y mejoras del artículo: http://www.freshegg.co.uk/blog/web-design/creating-lean-fast-web-pages-view-state

jueves, 18 de junio de 2015

Jugar Riven, la sequela de Myst por Steam y parche al Español

En Steam están con las famosas Summer Sales hasta el 21/junio y el clásico juego Riven, la secuela de Myst está a 2 dólares!: http://store.steampowered.com/app/63610/.


Ahora, si probamos el juego de Steam, (en mi caso lo probé con Windows 8.1), veremos que está tanto textos como voces en Inglés. Para dejar los textos y las voces en Español encontré este grandioso parche:

http://www.clandlan.net/foros/topic/76623-traduccion-riven-the-sequel-to-myst/

Aquí están los enlaces directos:

https://mega.co.nz/#!uE5mhAYA!lWY5qKQ767FM9nyryv8dH9WagTeaH0fzOWfVbgCpjj8
https://mega.co.nz/#!rA4DiT4S!V3sA6D1nZXG2_VatV9qw6sHKmjlMcMT2UsEjjs3D4sE
https://mega.co.nz/#!mRRT2bwZ!pfruCB0lbfLNizF9ktfhK_U5byRmd4IlfsbjZI37gvA
https://mega.co.nz/#!DchCVIwQ!bdb_hC7eJMTKcg5yvOUK3faGT6c4Ti3aobZNQ2GgC_M

Estos 4 archivos que sumados pesan 1.83 GB, se deben descomprimir en una carpeta. Finalmente quedará una carpeta Data con varios archivos adentro pesando 2.67 GB.

Luego copias el contenido de ese Data dentro de:

C:\Program Files (x86)\Steam\steamapps\common\Riven\Data

Finalmente probamos de nuevo el juego y listo. Con la tecla ALT puedes guardar una partida, cargar o salir del juego.

En mi caso guarde una partida cuando lo tenía en Inglés, luego pasé al Español y pude cargar la partida normalmente.

NOTA 1: El juego tiene algunos problemas a veces y se cuelga en Windows XP/Vista/8/7, por lo que cada vez que salves, hazlo en 3 partidas a la vez (usando SAVE AS/GUARDAR COMO). Me ha pasó 2 veces un mismo día que estaba salvando y se colgó justo cuando salvaba, luego al cargar no me dejó ya que el archivo estaba corrupto :(

NOTA 2: A veces inicias el juego y cuando quieres cargar, el juego no te deja o presionas la tecla ALT y no sale el menú Load/Cargar. En ese caso, espera los videos, presiona ESPACIO para saltártelos, y al final cuando tengas el control del mouse, allí presiona ALT para cargar.



miércoles, 17 de junio de 2015

¿Cómo determinar que cuenta es la que IIS usa para ejecutar un sitio Web?

Es importante entender que cuenta es la que IIS ejecuta en un sitio web dado, sobretodo cuando necesitas hacer cambios a las opciones de seguridad. Por ejemplo, tu aplicación web escribe archivos en el disco o en una base de datos (por ejemplo un Access .mdb) y te toca darle los permisos correctos a dicha carpeta o base de datos. Antes de cambiar esas opciones de seguridad, deberías saber que cuenta está usando IIS. Este artículo detalla varias opciones disponibles, tanto para el ASP clásico como para ASP.NET.

Hay una gran diferencia entre las aplicación ASP y ASP.NET cuando se quiere determinar el contexto de usuario que ejecuta el IIS, así que este documento está dividido en dos secciones: ASP Clásico y ASP.NET.

ASP Clásico

Por defecto, si un sitio web que permite acceso anónimo, esta cuenta es llamada IUSR_NombreMáquina, donde NombreMáquina es el nombre del computador. Sin embargo, cuando usas un mecanismo de seguridad en IIS diferente a acceso Anónimo, puedes cambiar manualmente la cuenta que usa IIS, o puedes correr tu sitio web en modo "Out Of Process", o quizá usar la cuanta de otro usuario. La siguiente tabla lista las posibles cuentas de usuarios que IIS usa en diferentes escenarios:

Escenario: El Sitio Web / Directorio Virtual / Aplicación está configurada como Anonymous Access.
Cuenta usada: IUSR_NombreMáquina

Escenario: El Sitio Web / Directorio Virtual / Aplicación está configurado como Anonymous Access, y a la vez esta como "Out Of Process" (el campo Application Protection del IIS está seteada como High en el tab "Home Directory" o el tab de Virtual Directory de tu aplicación web)
Cuenta usada: IWAM_NombreMáquina

Escenario: El Sitio Web / Directorio Virtual / Aplicación está configurado como Basic Authentication o Integrated Windows Authentication.
Cuenta usada: La cuenta que usas para logearte en la aplicación web.

Escenario: El Sitio Web / Directorio Virtual / Aplicación está configurado como Anonymous Access, pero manualmente cambias la cuenta usada para usar anonymous access.
Cuenta usada: La cuenta que especificas.

Para encontrar como está configurado tu sistema, sigue estos pasos:

  • Ve al Administrative Tools -> Internet Information Services:

Figura 1: Internet Information Services del IIS 5.

  • Expande el lado izquierdo y verás Default Web Site. Si estás configurando otro Sitio Web / Directorio Virtual / Aplicación, selecciónalo en vez del por defecto. Este artículo asume que estás configurando Default Web Site.
  • Botón derecho sobre Default Web Site y escoge Properties.
  • Abre el tab Directory Security y haz clic en el botón Edit... en la sección Anonymous access y authentication control. Verás una pantalla similar a esta:

Figura 2: El diálogo Authentication Methods para un sitio dado en IIS 5.

  • Si está chequeado Anonymous access (como la pantalla de arriba), el nombre usuario que vez en el campo User name es la cuenta de IIS que se usa. Si no está chequeado Anonymous access y si lo está Basic y/o Integrated Windows authentication, la cuenta que estás usando para logearte al sitio web es usado por IIS. Nota que cuando está activo Anonymous access, no importa si está chequeado Basic o Integrated authentication; la cuenta usada por IIS sigue siendo la anonymous, IUSR_NombreMáquina o la cuenta.
  • Finalmente tienes que chequear si el sitio está corriendo Out of Process. Para hacer esto, cierra del diálogo Authentication Methods, y ve al tab Home Directory: 

Figura 3: El tab Home Directory IIS 5.

Figura 4 A: El tab Home Directory IIS 6.

Figura 4 B: IIS 5 Isolation mode en IIS 6. La cuenta de usuario que se asigna en este caso es la llamada ASPNET account.

  • Si la Application Protection está como Alto (High) (Aislada o Isolated) y estás usando Anonymous Access, la cuenta que está usando IIS es IWAM_NombreMáquina.
    Nota: Aislar una app significa que se configura para que corra como un proceso (espacio de memoria) que está separado del servidor web y de otras aplicaciones.
    En todos los restantes escenarios, IIS estará usando la cuenta determinada por los pasos anteriores.

ASP.NET

Para  ASP.NET, la cosa es un poco diferente. Por defecto, ASP.NET corre con una cuenta especial llamada ASPNET. Esta cuenta es la cuenta con "menos privilegios", lo que significa que está restringida a algunas pocas cosas que puede hacer en el sistema.

Para hacer un poco más confusas las cosas, en Windows Server 2003 que tiene IIS 6, un cuenta llamada Network Service (en los Windows en Español es Servicio de Red) es usada por defecto, en vez de la cuenta ASPNET. En Windows Server 2008 R2 que tiene IIS 7.5 es lo mismo, Network Service es la cuenta por defecto.

Nota: Todas las aplicaciones corren en un proceso.
En IIS 5 (y IIS 6 en modo de Isolation IIS 5), las aplicaciones web corren en el proceso llamado ASP.NET Worker Process (aspnet_wp.exe). Por defecto este proceso corre con la cuenta ASPNET.
En IIS 6 y superiores, las aplicaciones corren bajo el proceso llamado IIS Worker Process (w3wp.exe). Por defecto este proceso corre con la cuenta Network Service.

En IIS 6 había un grupo llamado IIS_WPG, el cual es un contenedor de todos las identidades de todos los applicacion pool.

Desde IIS 7 hacia arriba tenemos:

  • La cuenta IUSR reemplaza IUSR_NombreMáquina. No requiere password por ser del sistema.
  • El grupo IIS_IUSRS reemplaza al grupo IIS_WPG.

Así, si estás usando Anonymous Access o Basic / Integrated security, la cuenta siempre será ASPNET o la cuenta Network Service.

Para ver que tipo de acceso estás usando en IIS 7.5:



Figura 5: Modos de autenticación en IIS 7.5. Por defecto Autenticación Anónima está activa por defecto.

Figura 6: En IIS 6 hacia arriba, se puede configurar la identidad del AppPool. En IIS 7.5 por defecto es ApplicationPoolIdentity, en IIS 6/7 es NetworkService pero permite cambiarla a ApplicationPoolIdentity si deseas.

Figura 7: Seteando una identidad NetworkService

Figura 8: El grupo IIS_IUSRS (de IIS 7 hacia arriba) con las cuentas dinámicas APPPOOL/Sitio X.

Sin embargo, puedes cambiar esa cuenta modificando el web.config de la app. Para hacer esto, agrega <identity impersonate="true" /> en la sección <system.web>. Si agregas el elemento, IIS usará el usuario actual en vez de la cuenta ASPNET. Esto significa que con Anonymous Access activado, esta cuenta sería la cuenta anónima. Usualmente esta es la cuenta IUSR_MachineName, pero si usas ASP Clásico chequea IIS, el usuario seteado en User Name (Figura 2).

Si no estás usando Anonymous Access, pero si Basic o Integrated Security, la cuenta que se usa es aquella del usuario actual logeado. Puedes también explícitamente setear una cuenta dada con los atributos username y clave del elemento <identity>.

La siguiente tabla lista las diferentes posibilidades. La primera columna determina si se activa o no la impersonation en el archivo Web.Config. La segunda y tercera columna lista las opciones con y sin acceso Anonymous:

ASP.NET Impersonation: Desactivado
Acceso anónimo: cuenta ASPNET o Network Service
Acceso no anónimo (Basic, Integrated, otro): cuenta ASPNET o Network Service

ASP.NET Impersonation: Activada
Acceso anónimo: IUSR_NombreMáquina
Acceso no anónimo (Basic, Integrated, otro): usuario autenticado

ASP.NET Impersonation: Activada con una cuenta de usuario
Acceso anónimo: la cuenta dada
Acceso no anónimo (Basic, Integrated, otro): la cuenta dada

Resumen

La mayor parte del código ejecutado en una aplicación web se hace bajo un contexto de un IIS worker process y lo típico es que ese proceso corra con un identidad configurada en el application pool.
Por defecto, los AppPool están configurados para usar una cuenta interna, en IIS 7 es la cuenta Network Service, en IIS 7.5 es una cuenta virtual llamada ApplicationPoolIdentity que en verdad es una cuenta con un ID único, el nombre de la cuenta es IIS AppPool\host (ID único) por ejemplo: IIS APPPOOL\Misitio.cl (S-1-5-82-1545844221-6599888).
Cuando se inicia el worker process, en IIS 7 o superior, se hace automáticamente miembro del grupo IIS_IUSRS. En IIS 6 se hace miembro de IIS_WPG. IIS puede crear el grupo IIS_WPG por razones de retrocompatibilidad, en ese caso, IIS_IUSRS se hará miembro del grupo IIS_WPG.
Además, cierto código de la aplicación puede ejecutarse con la identidad del usuario autenticado asociado a cada request.

En resumen tenemos 2 contextos de identidad según lo que la aplicación necesita:

1. Identidad del AppPool: se usa cuando se accede a todos los archivos necesarios para la ejecución del worker process, cuando se accede al web.config, aplicaciones FASTCGI o ejecución de aplicaciones .Net.
Identidades involucradas (pueden ser las 3 a la vez): Primero una de estas 4: Network Service, ApplicacionPoolIdentity, LocalService o LocalSystem. Aparte está involucrada la cuenta de grupo IIS_IUSRS en IIS 7 o superior, IIS_WPG en IIS 6 y por último la cuenta Aplication Pool SID (IIS APPPOOLL\MiSitio.cl).

2. Usuario autenticado: Se usa para acceder a archivos estáticos, correr extensiones ISAPI o programas CGI, ejecutar aplicaciones FastCGI (si está activado impersonate), ejecutar aplicaciones .NET (si está activado impersonate).
Identidades asociadas (pueden ser 2): IUSR es por defecto cuando la autenticación es anónima en IIS 7, en IIS 6 es IUSR_NombreMáquina. Si no, es el usuario configurado en el Pool en Custom Account, alguna de las opciones de Application Pool Identity: Network Service, ApplicacionPoolIdentity, LocalService o LocalSystem. La segunda posible identidad asociada es el usuario autenticado si hay tokens en caso de que esté siendo usado Windows Authentication.

Permisos a carpetas


Vamos al asunto práctico de todo esto. Si debes darle permiso a una carpeta en particular (o archivo) ya que la aplicación te da error de permisos, ¿a qué cuenta de Windows darle?

Depende, si los archivos son vitales para la ejecución del worker process o aplicación web:

  • Si estás con IIS 5, dale a ASPNET.
  • Si estás con IIS 6, dale permisos a la cuenta Network Service, ApplicacionPoolIdentity (IIS APPPOOLL\MiSitio.cl), LocalService o LocalSystem (según como lo tengas configurado). Si IIS 6 está corriendo como IIS 5 Isolation mode, la cuenta a darle permisos sería ASPNET. Otra alternativa sería darle permiso al grupo de todos los pools, IIS_WPG, pero esto sería menos seguro.
  • Si estás con IIS 7 o superior, dale permisos Read o Full Control según el caso al grupo IIS_IUSRS del equipo local.

Ahora, si la carpeta es de archivos estáticos (imágenes, CSS/JS, carpeta con logs, base de datos MDB, etc.) y de uso de la aplicación:

  • Si estás con IIS 5, dale a IUSR_NombreMáquina si es acceso anónimo. Si es anónimo pero es out-of-process, dale a IWAM_NombreMáquina, sino es anónimo, dale a la cuenta dada.
  • Si estás con IIS 6, dale a la cuenta del Pool en particular, cuenta IUSR_NombreMáquina, en caso de autenticación anónima. Si no es anónimo, dale a Network Service, ApplicacionPoolIdentity (IIS APPPOOLL\MiSitio.cl), LocalService o LocalSystem (según como lo tengas configurado). Lo otro sería darle al grupo que tiene los usuarios del AppPool, IIS_WPG, pero esto sería menos seguro.
  • Si estás con IIS 7 o superior, dale permisos Read o Full Control según el caso al grupo IIS_IUSRS del equipo local.

Cuentas y grupos según IIS


  • ApplicationPoolIdentity: es una identidad, una cuenta virtual que puedes seleccionar en el AppPool del IIS. En IIS 7.5 es la que está por defecto. En IIS 6 y 7 por defecto la identidad es Network Service. ApplicationPoolIdentity crea una cuenta de usuario dinámico con un ID único. Por ejemplo si mi sitio web es MiSitio, la cuenta que se crea dinámicamente en el sistema es IIS APPPOOL / MiSitio. Accede a la red con esta misma cuenta. Esta cuenta permite darle permisos solo a este usuario que es de ese único AppPool y no a todos. Además, esta cuanta dinámica pasa a ser parte del Grupo IIS_IUSRS/IIS_WPG.
  • Network Service / Servicio de red: es la cuenta usada por IIS 6 en adelante que corre cuando el acceso es anónimo sin impersonation. Se creo con Windows Server 2003. Tiene muy pocos privilegios locales, incluso menos que LocalSystem y menos que la cuenta Administrador. Tiene acceso a la red. El worker process del AppPool corre con esta cuenta en IIS 6 y IIS 7 por defecto, pero la puedes cambiar.
  • LocalService: cuenta local del sistema, muy pocos privilegios, similar a cuenta Network Service pero sin acceso a la red.
  • LocalSystem: cuenta del sistema, es una cuenta local, pertenece al grupo de administradores, tiene acceso a todo el equipo. No tiene acceso a la red.

IIS 5


  • ASPNET: es una cuenta del sistema usada por IIS 5 para ejecutar aplicaciones .NET. Se crea cuando se instala .NET Framework.
  • Anonymous Access: es la autenticación por defecto. Usa la cuenta ASPNET que pertenece al grupo Guest. IIS no pedirá un nombre de usuario ni clave a algún request.
  • Basic Authentication: El cliente envía el nombre de usuario y contraseña en un string codificado como base64. Se recomienda que sólo se use en HTTPSya que no es muy seguro.
  • Digest Authentication: Hecho para reemplazar Basic Authentication, donde primero el servidor envía un string de datos random llamados nonce, luego el cliente envía el usuario, contraseña como hash hacia el servidor.
  • Integrated Windows Authentication (NTLM): El cliente envía usuario y contraseña como hash a través de la red. El navegador entiende que es información encriptada.

IIS 6


  • ASPNET: es una cuenta usada por IIS 6 pero sólo si está en IIS 5.0 isolation mode para ejecutar aplicaciones .NET.
  • IUSR_NombreMáquina: es la cuenta de usuario por defecto para el acceso anónimo a IIS.
  • IWAM_NombreMáquina: es la cuenta de usuario para ejecutar aplicaciones out-of-process en IIS 5.0 isolation mode.
  • IIS_WPG: cuenta de grupo con permisos y privilegios mínimos del usuario necesarias para crear y ejecutar un worker process en el servicio web.
  • Anonymous Authentication / Autenticación Anónima: es lo mismo que lo anterior pero se renombra así desde IIS 6 en adelante. Es la autenticación por defecto.

IIS 7


  • IUSR: en IIS 7 reemplaza al IUSR_NombreMáquina del IIS 6.
  • IIS_IUSRS: en IIS 7 reemplaza al grupo IIS_WPG del IIS 6.
  • Certificate Authentication: En esta versión de IIS, permite autentificar al cliente automáticamente al usar un certificado, es bastante seguro.

IIS 7.5 y superior


  • ApplicationPoolIdentity: es la identidad por defecto de los AppPool desde el IIS 7.5, antes era NetworkService.

Referencias



Traducido, comentado y completado con aspectos actuales del artículo: http://imar.spaanjaars.com/287/how-do-i-determine-the-security-account-that-iis-uses-to-run-my-web-site

sábado, 13 de junio de 2015

The Longest Journey en Steam y parche al español

The Longest Journey, juego que salió en el mercado en 1999, es un clásico de la aventura gráfica. Por las grandiosas rebajas Summer Sale de Steam está a 4.99 USD hasta el 22/junio, bastante económico.



Esta guía es para dejarlo en Español, voces y textos gracias a WolfBelmi88.

Probando el juego recién bajado

Al bajarlo y probarlo de una en Windows 8.1 en Español funciona ok, se abre a 640x480 a full screen.

En el juego puedes presionar:

  • F2 salvar
  • F3 cargar
  • F10 salir, luego Y o S

Si al presionar alguna de estas teclas aparece una rectángulo en blanco, son ventanas de Window antiguas, donde lo más seguro es que hay un Aceptar o Cancelar, por lo que puedes presionar S o Y para indicar Si y con N es no.


Parchando el juego al español

Bajar el parche que contiene un instalador, pesa alrededor de 531 MB:

http://www.mediafire.com/download/758487s15wb9kf8/Traduccion+ESP+The+Longest+Journey.exe

Al abrir el instalador puede que indique la ruta por defecto:

C:\Archivos de programa (x86)\Steam\SteamApps\common\The Longest Journey

en mi caso lo cambié por

C:\Program Files (x86)\Steam\steamapps\common\The Longest Journey

Aceptar y esperar que se parche.

Si te pierdes en los pasos, la autora hizo un video explicativo:


Luego de parchado, ir a Steam e iniciar el juego y estará en español.



Bueno, espero les sirva como a mi. Gracias WolfBelmi88.

Más info: http://steamcommunity.com/sharedfiles/filedetails/?id=338452663

viernes, 5 de junio de 2015

Resolución de problemas con Forms Authentication

Herramientas usadas


  • LogParser 2.2
  • Fiddler
  • Microsoft Network Monitor 3.4

Resumen


A menudo, cuando usas Forms Authentication en una aplicación ASP.NET (no aplica para aplicaciones MVC), se da la necesidad de tener a mano una guía de resolución de problemas cuando un request sucede que intermitentemente la aplicación te redirige a la página login de ese mismo sitio. En un ambiente de Desarrollo puedes fácilmente debugear este problema atachando el proceso en el Visual Studio. En ambiente productivo, sin embargo, la tarea se vuelve muy complicada. Para tracear un problema como este, debes logear toda la información que puedas obtener relativa al problema, hasta llegar a la raíz misma de este.

En esta guía, mostraremos un resumen de lo que es el Forms Authentication. Veremos los escenarios en que un usuario puede ser redirigido a la página de login y como capturar datos que sean relevantes para aislar el problema. También veremos como implementar una interfaz IHttpModule para logear información relativa a Forms Authentication.

Resumen de la Autenticación de ASP.NET Forms


La autenticación de formulario permite autenticar un usuario usando tu propio código para mantener el token de autenticación ya sea en una cookie o en la url de la página. La autenticación participa en el ciclo de vida de una página ASP.NET a través de la clase FormsAuthenticationModule. Puedes acceder a la información de la autenticación a través de la clase FormsAuthentication.

Para usar una autenticación de formulario, creas una página login que colecciona credenciales del usuario y que incluyen código para autentificar dichas credenciales. Típicamente configuras la aplicación para que haga un redirect a una página login cuando los usuarios intentan acceder a un recurso protegido, como una página que requiere autenticación. Si las credenciales del usuario son válidas, puedes llamar a métodos de la clase FormsAuthentication para hacer un redirect de vuelta al request que originalmente se solicitó el recurso con el ticket apropiado de autenticación (cookie). Si no quieres hacer un redirect, puedes solo obtener la cookie de autenticación del formulario o setearla. En los request siguientes, el navegador del usuario pasa la cookie de autenticación en el mismo request, el cual hace que se salte la página de login.

Por defecto, la clase FormsAuthenticationModule se agrega al archivo Machine.config. La clase FormsAuthenticationModule administra el proceso de FormsAuthentication.

La siguiente es una entrada del archivo Machine.config:

<httpModule> 
     <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />           
</httpModule>";

Configuras la autenticación por formulario usando un elemento de configuración. En el caso más simple, tienes una página login. En el archivo de configuración, especificas la URL donde se redirigirán los request no autentificados. Entonces defines las credenciales válidas, en un archivo web.config o en un archivo separado. El siguiente ejemplo muestra una sección de un archivo de configuración que muestra una página login ylas credenciales de autenticación del método Authenticate. Los passwords han sido encriptados usando el método HashPasswordForStoringInConfigFile.

<authentication mode="Forms"> 
     <forms name="MyAuthCookie" loginUrl="/Login.aspx">     
       <credentials passwordFormat="SHA1">        
         <user name="Kim" password="07B7F3EE06F278DB966BE960E7CBBD103DF30CA6" />         
         <user name="John" password="BA56E5E0366D003E98EA1C7F04ABF8FCB3753889"/>         
       </credentials>
     </forms>
</authentication>

Luego de una autenticación ok, el módulo de FormsAuthenticationModule setea el valor de la propiedad User a una referencia del usuario autentifico. El siguiente código de ejemplo muestra como leer con programación la identidad del usuario autentificado con formularios.

String authUser2 = User.Identity.Name;

Una forma conveniente de trabajar con formularios de autenticación es usar controles de ASP.NET membership y ASP.NET login. ASP.NET membership te permite guardar y administrar información del usuario e incluir métodos para autentificar usuarios. Controles de ASP.NET login trabajan en conjunto con ASP.NET membership. Estos encapsulan la lógica para consultar las credenciales del usuario, validar al usuario, recobrar o reemplazar passwords, etc. De echo, los controles de ASP.NET membership y ASP.NET login proveen una capa de abstracción sobre la autenticación de formulario. Esta características reemplazan la mayoría de todos le típico trabajo que generalmente haces cuando tienes que usar autenticación de formularios.

Escenarios


Razones en la que un request se auto redirige a la página login.aspx:

La cookie de autenticación se pierde.

Escenario 1:

Un usuario se logea en el sitio web y en algún punto, el cliente envía un request al servidor y la clase FormsAuthenticationModule no recibe la cookie o no puede leerla.

Escenario 2:

La cookie de autenticación puede perderse cuando el navegador del cliente alcanza el límite de cookies creadas. Por ejemplo en Internet Explorer el límite es 20. Cuando ingresa la cookie número 21, el navegador elimina una cookie de la colección. Si se elimina la cookie .ASPXAUTH, el usuario será redirigido a la página de login en el siguiente request.

Escenario 3:

Luego que el request sale del cliente, hay varias capas que pueden afectar a los paquetes que están siendo enviados. Para determinar si algún dispositivo de red está eliminando la cookie, tienes que capturar una traza de red en el cliente y en el servidor, y entonces buscar en el cuerpo del request si está la cookie. Debes asegurarte que en el request del cliente se envío la cookie y chequear con una traza si se recibió ficha cookie.

Time-out en el ticket de autenticación de formulario

Una cosa que debes tener en mente en las aplicaciones hechas con ASP.NET 2.0 o superiores, es que el timeout de la autenticación de formulario cambió a 30 minutos por defecto. Esto significa que luego de 30 minutos de inactividad, el usuario será reenviado al login (nota: Cada vez que se accede al sitio, se resetea el reloj a 30 minutos - así se cuenta sólo cuando no se está haciendo nada).

Si quieres cambiar el valor del timeout a uno más largo, solo debes cambiar el valor en el web.config local (el valor del timeout está en minutos):

<system.web> 
     <authentication mode="Forms">   
       <forms timeout="50000000"/>                 
     </authentication>
</system.web>

Escenario 4:

La autenticación del formulario puede dar timeout antes que el valor seteado en el archivo de configuración.

Si el ticket de autenticación por formulario es generado manualmente por código, el timeout del ticket sobreescribe el valor seteado en el archivo de configuración. Por lo tanto, si ese valor es menor que el valor del archivo de configuración, el ticket del formulario de autenticación expirará antes y viceversa. Por ejemplo, asumamos que el atributo timeout está seteado a 30 (30 min) en tag Form del archivo Web.config y por código valor de Expiration del ticket está en 20. En este caso, el ticket del formulario de autenticación expiará pasados los 20 minutos y no a los 30 y el usuario tendrá que logearse de nuevo.
Event code: 4005
Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired.

Escenario 5

Una aplicación web ASP.NET 4 usa autenticación de formulario y el visor de eventos dice:

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

Recopilación de datos y resolución de problemas

Resolución del problema 1:

Puedes determinar si un request no contiene una cookie activando el cookie logging de Microsoft Internet Information Services (IIS). Para hacer esto sigue estos pasos en IIS 6:

-Abre IIS Microsoft Management Console (MMC).
-Botón derecho en el sitio web y luego Properties.
-Botón en el tab Web Site y clic en Enable Logging.
-Asegúrate que el formato del log es W3C Extended Log File Format.
-Clic en Properties. -Clic en Advanced tab y clic en Extended Properties.
-Bajo las Extended Properties, selecciona el checkbox Cookie(cs(Cookie)) y Referer (cs(Referer)). En IIS 7 es similar: Cuando seleccionas el formato "W3C" del combo Format y en "Select Fields" selecciona los 2 checkbox de las cookies.

Luego que el problema ocurre, determina cual es el cliente tiene el problema dado su dirección IP. Filtra el log IIS, con la columna "client IP address".

Nota: Puedes usar Log Parser para formatear los logs del IIS. Baja Log Parser del sitio oficial de Microsoft: http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=24659

Un request con cookies quedará registrado así:

2015-06-02 19:54:41 172.31.2.11 POST /Ventas/TestRequest - 80 - 172.31.17.26 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/43.0.2357.81+Safari/537.36 Cookie1=Hola;+Cookie2=dyxj/ney47DaZiwEMxUJrw/RvTomKx;+Cookie3=NALDO; http://sitio.cl/ 200 0 0 378

Luego de que tengas la lista de request de un usuario específico, busca por los request de la página login. Ya sabes que hay un redirect a esta página, así que busca por los request que suceden antes de la redirección. Si ves que no hay cookie en dichos request, el cliente no la mandó o esta fue eliminada de la red entre el cliente y el servidor.

Nota: El primer request del usuario no tiene la cookie de autenticación a menos que crees un cookie persistente. El log del IIS sólo muestra las cookies que son recibidas en el request. El primer request que debería tener la cookie de autenticación será la request después que suceda se realice el login de forma correcta.

Resolución del problema 2:

Microsoft Internet Explorer tiene las siguientes limitaciones en cuanto a las cookies (limitaciones RFC 2109):
  • 300 cookies en total
  • 4096 bytes por cookie
  • 20 cookies por cada host o dominio

El artículo oficial es: http://support.microsoft.com/kb/306070

La cookie de autenticación puede perderse si se alcanzó el límite de cookies en el cliente. En Internet Explorer tiene la limitación de 20 cookies. Eso quiere decir que si llega una cookie 21, se sobreescribe la primera. Si la cookie .ASPXAUTH es eliminada, el usuario será redirigido a la página de login en el siguiente request. Puedes usar fiddler para ver los header de los request y response y así saber si el cliente está mandando la cookie o no. Puedes bajar Fiddler 2 de Telerik: http://fiddler2.com/fiddler2/

Ejecuta fiddler en el cliente, elimina las trazas http existentes, accede a tu aplicación que implementa la autenticación de formulario, logeate y observa el tráfico http en fiddler para ver si hay algún cambio de la cookie entre el cliente y el servidor. Luego que capturas el tráfico, si fue ok el login, haz doble clic al request para las respuestas, y en tab Cookie ver que se cree la cookie con Set-Cookie.

Por defecto Internet Explorer puede almacenar un máximo de 20 cookies por dominio. Si un servidor envía más de 20 cookies a un cliente, el navegador automáticamente elimina las cookies más viejas.

Cada cookie consiste en un par nombre-valor. Este par debe ser seguido por valores pares de atributos separados por punto y coma. Este límite ha sido aumentado para simplificar el desarrollo y hosting de aplicaciones web sobre dominios que deben usar cookies. Instalando el update 937143 incrementa el número de cookies que Internet Explorer puede almacenar por cada dominio de 20 a 50. Para más detalles mira este link: http://support.microsoft.com/kb/941495

Resolución del problema 3:

Luego que el request sale de un cliente, hay varias capas que pueden afectar a los paquetes que son enviados como un firewall, proxys o balanceadores de carga. Para determinar si un dispositivo de red está eliminando una cookie, tienes que capturar el tráfico de red entre el cliente y el servidor, y ver como está la cookie en el cuerpo del request. Tienes que ver el cliente y ver si la cookie se envió, y luego en el servidor ver la traza para asegurarte que llegó la cookie.

Request del cliente

Este es un request GET luego que el usuario ha sido autenticado. El ticket de autenticación está marcado en amarillo. Esto confirma que la cookie existe en el lado del cliente. Cuando usas una herramienta de captura de red, como Netmon, verás el tráfico que realmente es enviado a través del adaptador.


Request por el lado del servidor

Cuando ves que el request llegó al servidor, te debes asegurar que llegó la misma información que salió del cliente. Si el servidor no recibe la misma información, necesitas investigar otros dispositivos de la red para determinar donde se eliminó la cookie.

Nota: Ha habido casos de filtros ISAPI que eliminan las cookies. Si confirmas que el servidor web recibió la cookie, pero la cookie no se ve en los Logs del IIS, chequea los filtros ISAPI. Tienes que eliminar los filtros y validar que el problema se resolvió.

Resolución del problema 5:

-Si el escenario involucra una granja de servidores o web farm (un balanceador, distintos servidores, una base de datos, un worker process por cada sitio), los Machinekeys deberían ser los mismo en todos lados. Usa el mismo machinekey para mantener la consistencia entre todos los servidores de la granja:

<machineKey validationKey="87AC8F432C8DB844A4EFD024301AC..." decryptionKey="E001A307CCC8B1ADEA..." validation="SHA1" />

-Compara los valores de los timeout de ambos módulos de autenticación de formulario y el módulo sesión de todos los servidores.

-Compara la versión del archivo System.Web.dll dentro de la carpeta Framework de ASP.NET 4 entre todos los servidores de la granja. Cuando falla con el error: Forms authentication failed for the request. Reason: The ticket supplied was invalid. Esto pasa cuando alguno de los servidores no está en la misma versión de Update del MS .NET framework 4.

-Instala Reliability Update 1 para .NET Framework 4 kb2533523 en el servidor que falta y reiniciar ese servidor. Esto corregirá el problema: http://support.microsoft.com/kb/2533523

Fuente: http://www.iis.net/learn/troubleshoot/security-issues/troubleshooting-forms-authentication