Sto tentando di implementare l'autenticazione per un servizio REST implementato in WCF e ospitato su Azure. Sto usando HttpModule per gestire gli eventi AuthenticationRequest, PostAuthenticationRequest e EndRequest. Se manca l'intestazione di autorizzazione o se il token in esso contenuto non è valido, durante EndRequest sto impostando lo StatusCode sulla risposta su 401. Tuttavia, ho determinato che EndRequest viene chiamato due volte e nella seconda chiamata la risposta ha già intestazioni impostato, causando il codice che imposta lo StatusCode per generare un'eccezione.HttpModule EndRequest gestore chiamato due volte
Ho aggiunto i blocchi a Init() per garantire che il gestore non venisse registrato due volte; ancora funzionato due volte. Init() ha anche eseguito due volte, a indicare che due istanze di HttpModule erano state create. Tuttavia, l'utilizzo di Set Object ID nel debugger VS sembra indicare che le richieste sono in realtà richieste diverse. Ho verificato in Fiddler che è stata rilasciata una sola richiesta al mio servizio dal browser.
Se si passa all'utilizzo del routing global.asax anziché a seconda della configurazione dell'host del servizio WCF, il gestore viene chiamato una sola volta e tutto funziona correttamente.
Se aggiungo la configurazione alla sezione di configurazione system.web e alla sezione di configurazione system.webServer in Web.config, il gestore viene chiamato una sola volta e tutto funziona correttamente.
Quindi ho delle attenuazioni, ma non mi piace il comportamento che non capisco. Perché il gestore viene chiamato due volte?
Ecco un repro minima 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>
modulo HTTP:
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;
}
}
}
Usi URLRewrite nella vostra applicazione? Sembra che causi l'arresto di EndRequest due volte. –
Può essere abilitato in background? Non ho il UrlRewriteModule nel mio web.config. –
Io non la penso così. Questo è davvero strano, perché non posso dire che tutto il mio problema causato da UrlRewriteModule. Ma alcuni di loro lo sono. –