Estoy intentando implementar la autenticación para un servicio REST implementado en WCF y alojado en Azure. Estoy usando HttpModule para manejar los eventos AuthenticationRequest, PostAuthenticationRequest y EndRequest. Si falta el encabezado Authorization o si el token contenido en él no es válido, durante EndRequest estoy configurando StatusCode en la respuesta a 401. Sin embargo, he determinado que EndRequest se llama dos veces, y en la segunda llamada la respuesta ya tiene encabezados set, provocando que el código que establece StatusCode arroje una excepción.controlador HttpModule EndRequest llamado dos veces
Agregué bloqueos a Init() para garantizar que el controlador no se registrara dos veces; todavía corrió dos veces. Init() también se ejecutó dos veces, lo que indica que se crearon dos instancias del HttpModule. Sin embargo, usar Set Object ID en el depurador de VS parece indicar que las solicitudes son en realidad solicitudes diferentes. Verifiqué en Fiddler que solo se envió una solicitud a mi servicio desde el navegador.
Si cambio al uso del enrutamiento global.asax en lugar de depender de la configuración del host del servicio WCF, el controlador solo se llama una vez y todo funciona bien.
Si agrego la configuración a la sección de configuración de system.web así como a la sección de configuración de system.webServer en Web.config, el controlador solo se llama una vez y todo funciona bien.
Tengo mitigaciones, pero realmente no me gusta el comportamiento que no entiendo. ¿Por qué se llama al manejador dos veces?
Aquí es una repro mínima del problema:
Web.config:
<system.web>
<compilation debug="true" targetFramework="4.0" />
<!--<httpModules>
<add name="AuthModule" type="TestWCFRole.AuthModule, TestWCFRole"/>
</httpModules>-->
</system.web>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="TestWCFRole.Service1">
<endpoint binding="webHttpBinding" name="RestEndpoint" contract="TestWCFRole.IService1" bindingConfiguration="HttpSecurityBinding" behaviorConfiguration="WebBehavior"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost/" />
</baseAddresses>
</host>
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
<bindings>
<webHttpBinding>
<binding name="HttpSecurityBinding" >
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="AuthModule" type="TestWCFRole.AuthModule, TestWCFRole"/>
</modules>
<directoryBrowse enabled="true"/>
</system.webServer>
Http módulo:
using System;
using System.Web;
namespace TestWCFRole
{
public class AuthModule : IHttpModule
{
/// <summary>
/// You will need to configure this module in the web.config file of your
/// web and register it with IIS before being able to use it. For more information
/// see the following link: http://go.microsoft.com/?linkid=8101007
/// </summary>
#region IHttpModule Members
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
// Below is an example of how you can handle LogRequest event and provide
// custom logging implementation for it
context.EndRequest += new EventHandler(OnEndRequest);
}
#endregion
public void OnEndRequest(Object source, EventArgs e)
{
HttpContext.Current.Response.StatusCode = 401;
}
}
}
¿Utiliza UrlRewrite en su aplicación? Parece que causa que EndRequest se dispare dos veces. –
¿Se puede habilitar en segundo plano? No tengo el UrlRewriteModule en mi web.config. –
No lo creo. Esto es realmente extraño, porque no puedo decir que todo mi problema sea causado por UrlRewriteModule. Pero algunos de ellos son –