对应于IIS中的每一个虚拟目录,都会有一个应用程序域(domain)。这样,IIS就能将每个ASP.NET web
应用程序或者web service隔离开。这一点与经典的ASP不一样,ASP中的应用程序保护级别在IIS元信息中
配置,它决定了ASP应用程序是运行在IIS进程inetinfo.exe中,或者是在一个预定的Dllhost.exe实例中,
或者在一个Dllhost.exe共享实例中。

ISAPI接口提供了ASP.NET运行时与IIS之间的桥接作用,它是用非托管代码编写;
它非常精炼,仅仅提供了一种路由机制来把到达的请求传递到ASP.NET运行时。所有其他操作,甚至包括
处理请求的线程管理也在asp.net引擎和用户编写的代码中进行。
作为一种协议,ISAPI支持ISAPI扩展和ISAPI过滤器。ISAPI扩展是一个请求处理的接口,它提供处理web服务器
的输出和输出的逻辑。ASP和ASP.NET就是用ISAPI扩展来实现的,针对ASP.NET的扩展是<.NET FrameworkDir>\aspnet_isapi.dll。
我们可以通过使用aspnet_regiis.exe来注册使用特定版本的aspnet_isapi.dll来处理asp.net请求。
cd <.NET FrameworkDir>
aspnet_regiis -i
ISAPI过滤器允许我们查看进入IIS的每一个请求,
可以修改请求的内容或者改变请求处理的操作,例如请求信息的合法性验证。巧合的是,ASP.NET也提供了类似的概念:
HTTP Handler(相当于extension)和HTTP module(相对于filter)。

在IIS5中,aspnet_isapi.dll直接宿驻在进程inetinfo.exe中;另外,如果你设定网站或者虚拟目录的隔离
级别为中或者高,它会宿驻在另一个工作者进程叫aspnet_wp.exe。如果第一个ASP.NET请求到达该dll,它会
用可执行文件aspnet_wp.exe生成一个新的进程。并将请求交个这个进程去处理。这个进程接着会
装载并运行.net运行时。接下来的所以请求都将由ISAPI DLL通过命名管道被路由到该工作者进程处理。
在IIS6中,服务器进程(即inetinfo.exe)不再让第三方可执行代码(例如,ISAPI扩展)直接在其地址空间执行;
它总是会创建一个单独的工作者进程(叫w3wp.exe)-应用程序池(application pool)。ISAPI dll将在该进程中
被执行。w3wp.exe直接与内核态的驱动程序HTTP.SYS打交道。inetinfo.exe仅仅负责管理和配置服务。因此,IIS6
相比IIS5有较大的性能提升。此外,由于ISAPI DLL和.NET运行时运行在同一进程中,所以它们之间的通信也更加高效。

HTTP Module的使用:
1. 实现接口IHttpModule
2. 在web.config中增加配置节
   <configuration>
    <system.web>
        <httpModules>
        <add name="TestModule" type="WebApplication1.TestHttpModule, WebApplication1" />
        </httpModules>
    </system.web>
   </configuration>
HTTP Handler的使用:
1. 实现接口IHttpHandler(或者IHttpAsyncHandler),它只有一个方法ProcessRequest,但是WebForm和WebService都是通过Http Handler来
   实现的;
2. 在IIS中把.data文件扩展名映射到aspnet_isapi.dll;
3. 在web.config中增加配置节
   <system.web>
    <httpHandlers>
     <add verb="*" path="*.data" type="namespace.classname, assemblyname" />
    </httpHandlers>
   </system.web>

总结,ASP.NET请求如何从IIS一直到被处理并返回到客户端浏览器?
1. IIS获取请求
2. 查看文件扩展名映射至aspnet_isapi.dll
3. 进入工作者进程(IIS5中是aspnet_wp.exe,或者IIS6中是w3wp.exe)
4. .NET运行时被加载
5. IsapiRuntime.ProcessRequest()被所托管代码调用
6. 每一个请求会创建一哥IsapiWorkerRequest
7. HttpRuntime.ProcessRequest()被调用,并传入Work Request作为参数
8. 通过传入Work Request作为参数创建HttpContext对象
9. 传入HttContext,并调用HttpApplication.GetApplicationInstance()
10. HttpApplication.Init()开始流水线事件处理并hook httpModule和httphandle
11. HttpApplication.ProcessRequest()
12. 触发流水线事件处理
13. httphandler被调用
14. 控制重新返回到流水线事件处理,触发postrequest事件

ASP.NET安全验证要点
在经过验证httpmodule之后,HttpContext.User总是非空的;即便我们允许匿名访问
<authentication mode="none">,这时有一个特殊的非配置的httpmodule会对HttpContext.User
设置一个匿名的principal。所以,当我们创建自定义的验证模块时,总是需要创建IPrincipal对象
并将它赋给HttpContext.User。
form authentication --> GenericPrincipal(或者自定义类实现了接口IPrincipal)
windows authentication --> WindowsPrincipal
Advertisements