Tag Archives: excepciones

WCF: Auditar errores a nivel de servidor


Windows Comunication Foundation (WCF) fue la evolución lógica de los antiguos Web Services de .NET 2.0 dotando a estos de multiples mejoras.

Aunque hoy en día se ha convertido en el estandar de uso para el desarrollo de servicios webs centralizados en .NET hay algunas cosas que Microsoft no terminó de pulir o complicó más de la cuenta.

Una de ellas es la captura de excepciones que ocurran en el servidor que aloja el WCF cuando es invocado desde un cliente en concreto y en este pequeño artículo vamos a explicar como configurar el servicio WCF para que audite los errores ocurridos.

 

Las típicas excepciones a nivel de cliente como “An unsecured or incorrectly fault error” o “An error occurred when verifying security for the message” realmente esconden el verdadero motivo del error y el único modo de saberlo es indicarle al servicio WCF que inserte en el Visor de Sucesos de Windows los detalles de la excepción usando “Service Security Audit“.

Para ello necesitaremos modificar el Web.Config añadiendo en el tag <behavior> el tag <serviceSecurityAudit> como en el ejemplo:

<behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true"/>
        </behavior>
      </serviceBehaviors>     
    </behaviors>

Los parámetros de “serviceSecurityAudit” son:

  • auditLogLocation:
    • Define dónde se almacenará el log del WCF.
    • Tipos:
      • Default
        • Los eventos se escriben en el Visor de Sucesos.
      • Application
        • Los eventos se escriben en el Visor de Sucesos de “Application”
      • Security
        • Los eventos se escriben en el Visor de Suscesos de “Security”
  • serviceAuthorizationAuditLevel y messageAuthenticationAuditLevel
    • Indica si se van a auditar los eventos de autorización y autenticación respectivamente contra el WCF.
    • Tipos:
      • None
        • No se almacena nada.
      • Success
        • Sólo las peticiones exitosas.
      • Failure
        • Sólo los errores.
      • SuccessAndFailure
        • Se almacena todo.
  • suppressAuditFailure
    • Valor booleano que indica si se ignoran o no las posibles excepciones que ocurran al intentar escribir en el log (la típica excepción guardando la excepción). Por defecto si se falla al intentar guardar la excepción esta es capturada e ignorada.
 
Si, como en mi caso, queremos saber solo cuando falla basta con que pongamos los valores a “Failure” y tendremos una entrada en el Event Viewer de nuestro servidor con el texto completo y real de la excepción.

 

IMPORTANTE: Activar el Service Security Audit reduce considerablemente el rendimiento del servicio WCF. Mi recomendación es que se desactive si ya has resuelto el error o si no necesitas auditar nada más.

 

Espero que este pequeño tutorial os ayude a encontrar esos horribles errores ocultos en vuestros servicios WCF.

 

Nos vemos Compilando!!

Gestión de Errores en ASP .NET: customErrors y Error Handling en Global.Asax

Uno de los aspectos más importantes a tener en cuenta cuando se pasa a producción una aplicación es como vas a tratar los posibles errores que ocurran en ella.

Por defecto, si no modificamos nada y ocurre un error sin controlar, la aplicación nos mostrará una página con el siguiente texto:

 

Server Error in ‘/’ Application.


Runtime Error

Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine. 

Details: To enable the details of this specific error message to be viewable on remote machines, please create a <customErrors> tag within a “web.config” configuration file located in the root directory of the current web application. This <customErrors> tag should then have its “mode” attribute set to “Off”.

 

 

Este mensaje nos indica que ha ocurrido un error y no se muestra al visitante debido a la configuración del Web.Config que por defecto viene así:

 

<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>

La forma más rápida para poder ver el error es cambiar el “RemoteOnly” por “Off” pero esto no es para nada recomendable ya que muestra los errores a cualquier visitante de la web pudiendo poner en entredicho la seguridad del sistema.

La tercera configuración que permite el apartado “customErrors” es redirigir a una página específica de error y luego guardar el error en un fichero de log o base de datos o bien enviarlo por mail. 

 

Este tutorial explica cómo implementar esta última opción:

Primero: Modificamos el Web.Config para activar los errores personalizados para que redirija a la página “error.aspx”:

<configuration>
    <system.web>
        <customErrors mode="On" defaultRedirect="error.aspx"/>
    </system.web>
</configuration>

Segundo: Creamos la página “error.aspx” para indicar al usuario qué debe de hacer. Como ejemplo os dejo la página de error personalizada que hicimos en Domitienda.com:

Tercero: Sobreescribir el método “Application_Error()” del fichero “Global.asax” (si no tienes ese fichero en tu proyecto lo puedes agregar). Este método se ejecuta cada vez que ocurre un error sin capturar. En este ejemplo vamos a enviar un mail con el error para que podamos revisarlo y solventarlo cuanto antes:

 

void Application_Error(object sender, EventArgs e)
{

	try
	{
		//Obtenemos el error
		Exception ex = Server.GetLastError();

		//Formateamos el correo con los datos del error
		string bodyMail = "Error en Aplicación<br/>";
		bodyMail+= "<br/>Fecha: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
		bodyMail+= "<br/>Descripción: " + ex.Message;
		bodyMail+= "<br/>Origen: " + ex.Source;
		bodyMail+= "<br/>Pila: " + ex.StackTrace;

		System.Net.Mail.MailMessage oMsg = new System.Net.Mail.MailMessage();
		oMsg.From = new System.Net.Mail.MailAddress("error@mydomain.com");
		oMsg.To.Add("webmaster@mydomain.com");
		oMsg.Subject = "Error en Aplicación";
		oMsg.Body = bodyMail;
		oMsg.IsBodyHtml = true;

		System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("mail.mydomain.com");
		smtp.Credentials = new System.Net.NetworkCredential("error@mydomain.com","passCuentaCorreo");

		smtp.Send(oMsg);

		//Limpiamos el error 
		Server.ClearError();
	}
	catch(Exception errorEnEnvioDeError)
	{
		//En caso de fallar el envío de error podíamos probar un método alternativo como guardar "bodyMail" en un fichero de texto o en base de datos
	}
}

 

 

Con este sencillo método tendremos nuestra web protegida ante errores inesperados, el visitante verá una página de error más usable y el adminitrador de la web tendrá el mensaje de error en su buzón de correo inmediatamente para poder solventarlo cuanto antes.

Nos vemos Compilando!!