我正在嘗試爲在WCF中實現的REST服務實現身份驗證,並且託管在Azure上。我正在使用HttpModule來處理AuthenticationRequest,PostAuthenticationRequest和EndRequest事件。如果Authorization頭部丟失或者其中包含的令牌無效,那麼在EndRequest期間,我將響應上的StatusCode設置爲401。但是,我確定EndRequest被調用兩次,並且在第二次調用時,響應已經有頭設置,導致設置StatusCode的代碼拋出異常。HttpModule EndRequest處理程序調用兩次
我向Init()添加了鎖,以確保處理程序未被註冊兩次;仍然跑了兩次。 Init()也運行了兩次,表明正在創建兩個HttpModule實例。但是,在VS調試器中使用Set Object ID似乎表明請求實際上是不同的請求。我已經在Fiddler中驗證過,從瀏覽器只有一個請求發佈到我的服務中。
如果我切換到使用global.asax路由而不是取決於WCF服務主機配置,處理程序只調用一次,一切正常。
如果我將配置添加到system.web配置部分以及Web.config中的system.webServer配置部分,處理程序只調用一次,一切正常。
所以我有緩解,但我真的不喜歡行爲,我不明白。爲什麼處理程序被調用兩次?
這是問題的一個最小的攝製:
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模塊:
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;
}
}
}
你在你的應用程序中使用UrlRewrite?看來,它會導致EndRequest發起兩次。 –
它可以在後臺啓用嗎?我的web.config中沒有UrlRewriteModule。 –
我不這麼認爲。這真的很奇怪,因爲我不能說我所有的問題都是由UrlRewriteModule引起的。但其中一些是。 –