Tôi đang cố triển khai xác thực cho một dịch vụ REST được triển khai trong WCF và được lưu trữ trên Azure. Tôi đang sử dụng HttpModule để xử lý các sự kiện AuthenticationRequest, PostAuthenticationRequest và EndRequest. Nếu tiêu đề Cấp quyền bị thiếu hoặc nếu mã thông báo chứa trong đó không hợp lệ, trong EndRequest tôi đang đặt Mã trạng thái trên Phản hồi thành 401. Tuy nhiên, tôi đã xác định rằng EndRequest được gọi hai lần và cuộc gọi thứ hai phản hồi đã có tiêu đề thiết lập, gây ra mã mà đặt StatusCode để ném một ngoại lệ.Trình xử lý HttpModule EndRequest được gọi hai lần
Tôi đã thêm khóa vào Init() để đảm bảo rằng trình xử lý không được đăng ký hai lần; vẫn chạy hai lần. Init() cũng chạy hai lần, chỉ ra rằng hai cá thể của HttpModule đã được tạo ra. Tuy nhiên, bằng cách sử dụng Set Object ID trong trình gỡ lỗi VS dường như chỉ ra rằng các yêu cầu thực sự là các yêu cầu khác nhau. Tôi đã xác minh trong Fiddler rằng chỉ có một yêu cầu được cấp cho dịch vụ của tôi từ trình duyệt.
Nếu tôi chuyển sang sử dụng định tuyến toàn cầu.asax thay vì tùy thuộc vào cấu hình máy chủ lưu trữ dịch vụ WCF, trình xử lý chỉ được gọi một lần và mọi thứ hoạt động tốt.
Nếu tôi thêm cấu hình vào phần cấu hình system.web cũng như phần cấu hình system.webServer trong Web.config, trình xử lý chỉ được gọi một lần và mọi thứ hoạt động tốt.
Vì vậy, tôi có giảm nhẹ, nhưng tôi thực sự không thích hành vi mà tôi không hiểu. Tại sao trình xử lý được gọi hai lần?
Đây là một repro tối thiểu của vấn đề:
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ô-đun:
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;
}
}
}
Bạn có sử dụng UrlRewrite trong ứng dụng của bạn? Dường như, nó khiến EndRequest bắn hai lần. –
Có thể bật trong nền không? Tôi không có UrlRewriteModule trong web.config của tôi. –
Tôi không nghĩ vậy. Điều này thực sự kỳ lạ, bởi vì tôi không thể nói rằng tất cả các vấn đề của tôi gây ra bởi UrlRewriteModule. Nhưng một số trong số đó là. –