Archivo de la etiqueta: web.config

Optimizar cache en IIS

En este post aprenderemos a optimizar cache en IIS editando el web.config.

Si tu servidor de alojamiento web es IIS puedes mejorar la velocidad de tu sitio estableciendo el tiempo de la caché insertando dentro de <system.webServer> del archivo web.config de la raíz de tu aplicación web:

<staticContent>
<clientCache cacheControlMode=»UseMaxAge» cacheControlMaxAge=»7.00:00:00″ />
</staticContent>

Donde cacheControlMode puede tomar los valores:

  • «NoControl»: no se establece un tipo de caché para el sitio, con lo que tomará los valores globales de configuración heredados.
  • «DisableCache»: caché deshabilitada para el sitio.
  • UseMaxAge: se especifica una edad de expiración de la caché en el parámetro cacheControlMaxAge en días, horas, minutos y segundos (d.hh:mm:ss)
  • UserExpires: indica la fecha exacta de expiración de la caché.

Error de validación de viewstate MAC

En el supuesto de que instales tu aplicación web en una granja de servidores debes tener en cuenta que es posible que la validación del viewstate no se comporte correctamente. Como sabemos para un programador esto es un problema porque son errores que no se producen en nuestro equipo local de desarrollo sino que es en el despliegue.

El error

El error en cuestión es el siguiente:

Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey>….

ViewState MAC Farm

¿Por qué este error?

Como sabemos en asp.net existe el concepto del viewstate que permite guardar el estado de ciertos controles y partes de la página para ser reutilizados después de un postback. Esto que a priori es una ventaja implica el inconveniente de que un usuario malintencionado envíe una carga _VIEWSTATE y engañe a la aplicación y realice una acción que no se debería realizar.

Para evitar este tipo de ataque el campo _VIEWSTATE se protege codificándolo con un código de autenticación de mensajes (MAC). ASP.Net valida el MAC que se envía con la  carga cuando se produce un postback, si no coincide se produce un error en la validación del viewstate.

La clave que se utiliza para calcular el MAC está en el elemento machineKey de la aplicación en el archivo web.config.

Una de las causas más comunes que provocan este error es que nuestra aplicación está en una granja de servidores, en este caso cada uno de los servidores generará una machineKey para nuestra app y entonces ninguno acordará cual aplicar.

Solución

La mejor solución y más sencilla es aplicar una machineKey explícitamente en nuestro web.config. De esta manera cualquier servidor que pretenda ejecutar nuestra aplicación utilizará de manera obligada la clave que le establezcamos en este fichero.

¿Cómo generamos nuestra clave machinekey?

Para generarlo tenemos varias maneras pero yo recomiendo nunca utilizar sitios web donde se generan automáticamente ya que no sabemos si estas claves se han generado de forma segura o son guardadas para posibles usos malintencionados, buff ya sé que suena muy rebuscado pero no nos podemos fiar, solo debemos usar las claves generadas por nosotros mismos.

En este link podemos ver varias maneras para crear el machine.config.

¿En qué sección del web.config editamos nuestra machinekey?

El elemento <machineKey> solo es válido en el archivo Web.config en la raíz de la aplicación y no es válido en el nivel de subcarpeta (location).

<configuration>
  <system.web>
    <machineKey ... />
  </system.web>
</configuration>

 

Problemas con OWIN en un hosting compartido

Si vas a desarrollar una aplicación asp.net con OWIN y piensas alojarla en un servidor compartido debes tener esto en cuenta.

En muchos proveedores de hosting compartido tienen configurado en IIS el nivel de confianza high, medium, low… pero no está «Full».

Esto es importante porque los ensamblados OWIN necesitan para su perfecta ejecución el nivel de confianza Full. (trust level=»Full»). Este parámetro se puede configurar en el web.config pero será inútil ponerlo si a nivel de máquina el machine.config no permita sobrescribirlo.

trust_level

Los problemas con OWIN en un hosting compartido parten de que OWIN utiliza reflection para instanciar algunos objetos y la seguridad del servidor no lo permite.

Existen varias soluciones, pero todas pasan por contratar otro tipo de hosting:

  • Servidor Virtual, quizá la más económica priori.
  • Azure, se paga por recursos utilizados y es altamente escalable.
  • Servidor dedicado, seguro la menos económica.

Usar la reescritura URL en joomla! editando el web.config en IIS

Como sabréis las palabras contenidas en las direcciones URL son importantes para los buscadores a la hora del posicionamiento. Por ello es mucho más optimo tener una url del tipo:

http://posicionamiento-sitios-web.blogspot.com.es/mis-palabras-clave

que otra como la siguiente

http://posicionamiento-sitios-web.blogspot.com.es/index.php?article-id=4

Hay que aprovecharse de esto y «pasar» algunas palabras clave en cada una de las URL de nuestro sitio.

La mayor parte de los CMS que podemos utilizar actualmente están preparados para mejorar el posicionamiento orgánico. Entre estos CMS está joomla!.

Si tu servidor web es IIS con el módulo URL rewrite y tienes un sitio web en joomla! deberás editar el archivo web.config en la raíz de tu aplicación. En el apartado <system.webServer> inserta el siguiente bloque XML:


<rewrite>

<rules>

<rule name="Joomla! Rule 1" stopProcessing="true">

<match url="^(.*)$" ignoreCase="false" />

<conditions logicalGrouping="MatchAny">

<add input="{QUERY_STRING}" pattern="base64_encode[^(]*\([^)]*\)" ignoreCase="false" />

<add input="{QUERY_STRING}" pattern="(&gt;|%3C)([^s]*s)+cript.*(&lt;|%3E)" />

<add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />

<add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />

</conditions>

<action type="CustomResponse" url="index.php" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />

</rule>

<rule name="Joomla! Rule 2">

<match url="(.*)" ignoreCase="false" />

<conditions logicalGrouping="MatchAll">

<add input="{URL}" pattern="^/index.php" ignoreCase="true" negate="true" />

<add input="{URL}" pattern="/component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$" />

<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />

<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />

</conditions>

<action type="Rewrite" url="index.php" />

</rule>

</rules>

</rewrite>

Con esto IIS puede aprovechar unos patrones de expresiones regulares para convertir peticiones y transformarlas a urls con alias

Handler axd funciona correctamente en local pero no funciona en el servidor

Tengo una librería MSCaptcha que funciona correctamente en local pero al subir al servidor no funciona correctamente.

El problema surge de que IIS7 introdujo dos condiciones previas denominadas «integratedMode» y «classicMode«. Un handler que tiene una precondition «integratedMode« asociado a él sólo se puede cargar en un grupo de aplicaciones que tiene el «integratedMode« establecido en el conjunto de propiedades en la ApplicationPool. Handlers con la precondition «classicMode« sólo se cargarán en Grupos de aplicaciones que tienen la propiedad integratedMode establecida en falso.

En mi servidor local el pool de aplicaciones está en modo integrado con lo que la librería MSCaptcha funciona correctament pero en el servidor de producción está en modo clásico.

Para solucionarlo sin tener que cambiar configuraciones de servidor se puede establecer en el web.config una directiva para que el handler cargue con la configuración que decidamos.

En mi caso particular será:


<add name="MSCaptcha" verb="GET" path="CaptchaImage.axd" type="MSCaptcha.CaptchaImageHandler, MSCaptcha" preCondition="integratedMode"/>

De está forma he logrado que mi captcha se visualiza en el servidor.