AuthenticateRequest event
AuthenticateRequest event
问题
Q 1. To my understanding FormsAuthenticationModule
is subscribed to AuthenticateRequest
event, and thus only after this event is fired, is FormsAuthenticationModule
called. But the following quotes got me a bit confused:
-
The
AuthenticateRequest
event signals that the configured authentication mechanism has authenticated the current request.- Doesn’t the above quote suggest that when
AuthenticateRequest
event is raised, request (aka user) is already authenticated?
- Doesn’t the above quote suggest that when
-
Subscribing to the
AuthenticateRequest
event ensures that the request will be authenticated before processing the attached module or event handler.- As far as I understand this quote, if we subscribe to
AuthenticatedRequest
, then our event handler will be called prior toFormsAuthenticationModule
? ThusApplication_AuthenticateRequest()
will be called beforeFormsAuthenticationModule
is called?
- As far as I understand this quote, if we subscribe to
Q 2. Book I’m learning from suggests that within Application_AuthenticateRequest()
we are able to verify whether user is a member of specific role, and if not, we can add the user automatically:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated && Roles.Enabled)
{
//here we can subscribe user to a role via Roles.AddUserToRole()
}
}
Judging from the above code, Application_AuthenticateRequest()
is called after FormsAuthenticationModule
has been invoked, but somewhere else same book implies that Application_AuthenticateRequest()
is called prior to FormsAuthenticationModule
:
Application_AuthenticateRequest
is called just before authentication is performed. This is a jumping-off point for creating your own authentication logic.
What am I missing?
回答
It seems that the FormsAuthenticationModule gets handled first. This module is normally earlier than any custom module in the ASP.NET pipeline, so when AuthenticateRequest is fired, FormsAuthenticationModule will get called first, do its job and then your module's event handler will be called.
If you really want to dig deep into this, I suggest trying to debug the ASP.NET code yourself. Here is a post how to set up your VS:
EDIT: I was able to confirm this behavior by setting up a web project with custom module and event handlers in Global.asax. Take a look at the source code of HttpApplication.InitInternal, the order of initialization is as follows:
- initialization of integrated modules: FormsAuthenticationModule hooks up to HttpApplication.AuthenticateRequest event
- initialization of custom modules: custom module hooks up to HttpApplication.AuthenticateRequest event
- initialization of Global class (global.asax): here we hook up to the AuthenticateRequest event
- HttpApplication.InitInternal searches for methods on Global class following the specific name pattern (e.g. Application_AuthenticateRequest), matches them to event and hooks up
After the initialization, when the AuthenticateRequest fires, the event handlers are called in the order they where initialized, so:
- FormsAuthenticationModule.AuthenticateRequest event handler
- CustomModule.AuthenticateRequest event handler
- Global.AuthenticateRequest event handler
- Global.Application_AuthenticateRequest method
Unless I missed something, there is no mechanism for stopping the event handlers to fire, so no matter what the result of FormsAuthenticationModule.AuthenticateRequest, the next handlers will still be called. I hope that helps.
// System.Web.HttpApplication // Token: 0x0600077A RID: 1914 RVA: 0x0000E2E8 File Offset: 0x0000C4E8 internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) { this._state = state; PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); try { try { this._initContext = context; this._initContext.ApplicationInstance = this; context.ConfigurationPath = context.Request.ApplicationPathObject; using (new DisposableHttpContextWrapper(context)) { if (HttpRuntime.UseIntegratedPipeline) { try { context.HideRequestResponse = true; this._hideRequestResponse = true; this.InitIntegratedModules(); goto IL_6B; } finally { context.HideRequestResponse = false; this._hideRequestResponse = false; } } this.InitModules(); IL_6B: if (handlers != null) { this.HookupEventHandlersForApplicationAndModules(handlers); } this._context = context; if (HttpRuntime.UseIntegratedPipeline && this._context != null) { this._context.HideRequestResponse = true; } this._hideRequestResponse = true; try { this.Init(); } catch (Exception error) { this.RecordError(error); } } if (HttpRuntime.UseIntegratedPipeline && this._context != null) { this._context.HideRequestResponse = false; } this._hideRequestResponse = false; this._context = null; this._resumeStepsWaitCallback = new WaitCallback(this.ResumeStepsWaitCallback); if (HttpRuntime.UseIntegratedPipeline) { this._stepManager = new HttpApplication.PipelineStepManager(this); } else { this._stepManager = new HttpApplication.ApplicationStepManager(this); } this._stepManager.BuildSteps(this._resumeStepsWaitCallback); } finally { this._initInternalCompleted = true; context.ConfigurationPath = null; this._initContext.ApplicationInstance = null; this._initContext = null; } } catch { throw; } }
集成模式下的处理
// Token: 0x06000790 RID: 1936 RVA: 0x0000EFC2 File Offset: 0x0000D1C2 private void InitIntegratedModules() { this._moduleCollection = this.BuildIntegratedModuleCollection(HttpApplication._moduleConfigInfo); this.InitModulesCommon(); } // System.Web.HttpApplication // Token: 0x060007A6 RID: 1958 RVA: 0x0000FAC4 File Offset: 0x0000DCC4 private HttpModuleCollection BuildIntegratedModuleCollection(List<ModuleConfigurationInfo> moduleList) { HttpModuleCollection httpModuleCollection = new HttpModuleCollection(); foreach (ModuleConfigurationInfo moduleConfigurationInfo in moduleList) { ModulesEntry modulesEntry = new ModulesEntry(moduleConfigurationInfo.Name, moduleConfigurationInfo.Type, "type", null); httpModuleCollection.AddModule(modulesEntry.ModuleName, modulesEntry.Create()); } return httpModuleCollection; } // System.Web.HttpApplication // Token: 0x0600078F RID: 1935 RVA: 0x0000EF6C File Offset: 0x0000D16C private void InitModulesCommon() { int count = this._moduleCollection.Count; for (int i = 0; i < count; i++) { this._currentModuleCollectionKey = this._moduleCollection.GetKey(i); this._moduleCollection[i].Init(this); } this._currentModuleCollectionKey = null; this.InitAppLevelCulture(); }
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2019-07-17 Chrome Development Tool: [VM] file from javascript
2019-07-17 Forcepoint
2019-07-17 ASP.NET Web Optimization Framework
2017-07-17 常用快捷键
2017-07-17 Track Active Item in Solution Explorer
2015-07-17 Learning WCF Chapter2 Service Contracts
2015-07-17 Learning WCF Chapter2 WCF Contracts and Serialization