(本文资源全部来自于园子里各牛)
之前看jimmyzhang的asp.net运行原理,开篇既说要明白验证就要先看asp.net运行原理,不然用控件就是"微软的用户"了
现在看到这总算反应过来,原来验证是在HttpModule里进行的(目前观点).
首先来看一下HttpModule的生命周期
为了证明这个图,来看一下下面这段代码.
Code public class ValidaterHttpModule : IHttpModule{ public void Dispose() { } public void Init(HttpApplication application) { application.BeginRequest += new EventHandler(application_BeginRequest); application.EndRequest += new EventHandler(application_EndRequest); application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute); application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute); application.ReleaseRequestState += new EventHandler(application_ReleaseRequestState); application.AcquireRequestState += new EventHandler(application_AcquireRequestState); application.AuthenticateRequest += new EventHandler(application_AuthenticateRequest); application.AuthorizeRequest += new EventHandler(application_AuthorizeRequest); application.ResolveRequestCache += new EventHandler(application_ResolveRequestCache); application.PreSendRequestHeaders += new EventHandler(application_PreSendRequestHeaders); application.PreSendRequestContent += new EventHandler(application_PreSendRequestContent); } void application_PreSendRequestContent(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_PreSendRequestContent<br/>"); } void application_PreSendRequestHeaders(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_PreSendRequestHeaders<br/>"); } void application_ResolveRequestCache(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_ResolveRequestCache<br/>"); } void application_AuthorizeRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_AuthorizeRequest<br/>"); } void application_AuthenticateRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_AuthenticateRequest<br/>"); } void application_AcquireRequestState(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_AcquireRequestState<br/>"); } void application_ReleaseRequestState(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_ReleaseRequestState<br/>"); } void application_PostRequestHandlerExecute(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_PostRequestHandlerExecute<br/>"); } void application_PreRequestHandlerExecute(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_PreRequestHandlerExecute<br/>"); } void application_EndRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_EndRequest<br/>"); } void application_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; application.Context.Response.Write("application_BeginRequest<br/>"); }}
实现了IHttpModule接口.
运行如下:application_BeginRequestapplication_AuthenticateRequestapplication_AuthorizeRequestapplication_ResolveRequestCacheapplication_AcquireRequestStateapplication_PreRequestHandlerExecute
application_PostRequestHandlerExecuteapplication_ReleaseRequestStateapplication_EndRequestapplication_PreSendRequestHeaders
看来确实是如此.
下面就是实现用户验证的简单例子
Code public class UserAuthorizationModule : IHttpModule{ public void Dispose(){ } public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } void context_AcquireRequestState(object sender, EventArgs e) { // 获取应用程序 HttpApplication application = (HttpApplication)sender; // 检查用户是否已经登录 if (application.Context.Session["UserName"] == null || application.Context.Session["UserName"].ToString().Trim() == "") { // 获取Url string requestUrl = application.Request.Url.ToString(); string requestPage = requestUrl.Substring(requestUrl.LastIndexOf('/') + 1); // 如果请求的页面不是登录页面,刚重定向到登录页面。 if (requestPage != "Login.aspx") application.Server.Transfer("Login.aspx"); } else { // 已经登录,向每个请求的页面打印欢迎词。 application.Response.Write(string.Format("欢迎您!{0}!", application.Context.Session["UserName"])); } }}
Code public class SystemModuleAuthorizationModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } void context_AcquireRequestState(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; // 如果用户未登录,则无需检查模块授权,因为请求会被用户登录Module重定向到登录页面。 if (application.Session["UserName"] == null) return; // 获取用户名和Url string userName = application.Session["UserName"].ToString(); string url = application.Request.Url.ToString(); // 如果用户没有被授权,请求被终止,并打印提示信息。 if (!Validator.CanUseModule(userName, url)) { application.CompleteRequest(); application.Response.Write(string.Format("对不起!{0},您无权访问此模块!", userName)); } } } public class Validator { public static bool CanUseModule(string userName, string url) { if (!url.Contains("模块")) return true; else if (userName == "文野" && url.Contains("模块1")) return true; else if (userName == "stwyhm" && url.Contains("模块2")) return true; else return false; } }
在webconfig注册完成后,就可以运行看看效果了(页面上的关于session代码肯定再熟悉不过了).
这里两个自定义的HttpModule实现了它们各自所要达到的过滤请求的功能,一个限制用户登录,一个限制模块访问,当然实际应用中比这要复杂许多。这样的验证方式是简单的、安全的,代码在修改时只要修改相应的HttpModule就可以了,无需在每个页面都写相同的验证代码,也不会发生在Url地址栏里输入一段Url就可以跳过登录及其它验证的情况了。在这两个HttpModule中,因为都要涉及到对Session的访问,所有都使用了AcquireRequestState事件
一个完整的HTTP请求在ASP.NET Framework的处理过程如下:
HttpRequest ——> inetinfo.exe ——> ASPNET_ISAPI.dll ——> Http Pipeline ——> ASPNET_WP.exe ——> HttpRuntime ——> HttpApplication Factory ——> HttpApplication ——> HttpModule ——> HttpHandler Factory ——> HttpHandler ——> HttpHandler.ProcessRequest()
HTTP Handler提供了类似于ISAPI Server Extention的功能,而HttpModule实现了类似于ISAPI Filter的功能。使用自定义的Handler会覆盖系统默认的Handler,而Module是可以多个同时存在的。
转载于:https://www.cnblogs.com/renjuwht/archive/2009/06/21/1507843.html
