ASP.NET Pipeline Processing

来源:互联网 发布:mac系统插鼠标没反应 编辑:程序博客网 时间:2024/06/05 20:22
Team LiB
Previous Section Next Section
http://man.ddvip.com/web/bsaspnetapp/LiB0321.html

ASP.NET Pipeline Processing

ASP.NET authentication and authorization mechanisms are implemented using HTTP module objects, which are invoked as part of the standard ASP.NET pipeline processing. Individual Web requests and responses pass through a pipeline of objects as shown in Figure 2.

 
Figure 2: ASP.NET pipeline processing

The ASP.NET pipeline model consists of an HttpApplication object, various HTTP module objects, and an HTTP handler object, together with their associated factory objects, which have been omitted from Figure 2 for clarity. An HttpRuntime object is used at the start of the processing sequence and an HttpContext object is used throughout the lifecycle of a request to convey details about the request and response.

The following list explains the responsibilities and operations performed by the objects associated with the HTTP processing pipeline:

  • The HttpRuntime object examines the request received from IIS and dispatches it to an appropriate instance of the HttpApplication object to process the request. There is a pool of HttpApplication objects in each application domain in Aspnet_wp.exe. There is a one-to-one mapping between application domains, HttpApplication objects and IIS virtual directories. In other words, ASP.NET treats separate IIS virtual directories as separate applications.

     Note 

    There is one instance of HttpRuntime in every Web application domain.

  • The HttpApplication objects control the pipeline processing. An individual HttpApplication object is created to handle each simultaneous HTTP request. HttpApplication objects are pooled for performance reasons.

  • HTTP module objects are filters that process HTTP request and response messages as they flow through the pipeline. They can view or alter the content of the request and response messages. HTTP modules are classes that implement IHttpModule.

  • HTTP handler objects are the endpoints for HTTP requests and provide the request processing for specific file types. For example, one handler processes requests for *.aspx files while another processes requests for *.asmx files. The HTTP response message is generated and returned from the HTTP handler. HTTP handlers are classes that implement IHttpHandler.

  • An HttpContext object is used throughout the pipeline to represent the current Web request and response. It is available to all modules in the pipeline and the handler object at the end of the pipeline. The HttpContext object exposes various properties including theUser property which contains an IPrincipal object that represents the caller.

The Anatomy of a Web Request

The ASP.NET ISAPI library (Aspnet_isapi.dll) runs inside the IIS process address space (Inetinfo.exe). It dispatches requests to the HttpRuntime object within the ASP.NET worker process (Aspnet_wp.exe). The following set of actions occurs in response to each Web request received by ASP.NET:

  • The HttpRuntime object examines the request and forwards it to an instance of an HttpApplication object.

    There is at least one HttpApplication object instance per application domain (the objects are pooled) and one application domain per IIS virtual directory. The initial request for a file in a particular virtual directory results in a new application domain and a newHttpApplication object being created.

  • A list of HTTP modules is read from Machine.config (they are contained within the <httpModules> element). Additional custom HTTP modules can be added to Web.config for a specific application. The default <httpModules> element within Machine.config is shown in the following code snippet.

    <httpModules>  <add name="OutputCache"        type="System.Web.Caching.OutputCacheModule"/>  <add name="Session"        type="System.Web.SessionState.SessionStateModule"/>  <add name="WindowsAuthentication"        type="System.Web.Security.WindowsAuthenticationModule"/>  <add name="FormsAuthentication"        type="System.Web.Security.FormsAuthenticationModule"/>  <add name="PassportAuthentication"        type="System.Web.Security.PassportAuthenticationModule"/>  <add name="UrlAuthorization"        type="System.Web.Security.UrlAuthorizationModule"/>  <add name="FileAuthorization"        type="System.Web.Security.FileAuthorizationModule"/></httpModules>

    The authentication modules hook the AuthenticateRequest event, while the authorization modules hook the AuthorizeRequest event.

    The request passes through every module in the pipeline, although only a single authentication module is loaded. This depends on the configuration of the <authentication> element in Web.config. For example, the <authentication> element that follows results in the WindowsAuthenticationModule being loaded.

    <authentication mode="Windows" />
  • The activated authentication module is responsible for creating an IPrincipal object and storing it in the HttpContext.User property. This is vital, because the downstream authorization modules use this IPrincipal object in order to make authorization decisions.

    In the absence of authentication (for example, where anonymous access is enabled within IIS and ASP.NET is configured with <authentication mode=”None” />), there’s a special non configured module that puts a default anonymous principal into theHttpContext.User property. As a result, HttpContext.User is always non-null after authentication.

    If you implement a custom authentication module, code within the custom module must create an IPrincipal object and store it in HttpContext.User,

     Note 

    ASP.NET also wires up Thread.CurrentPrincipal based on HttpContext.User after the AuthenticateRequest event.

  • The HttpApplication fires the AuthenticateRequest event, which can be hooked in global.asax. This allows you to inject custom processing code; for example, to load the set of roles associated with the current user. However, note that theWindowsAuthenticationModule does this automatically. The role list is obtained from the set of Windows groups in which the authenticated Windows user is a member.

  • After the appropriate authentication module has finished its processing, the authorization modules are called if the request hasn’t been aborted.

  • When the UrlAuthorizationModule is called, it checks for an <authorization> tag in Machine.config and Web.config. If present, it retrieves the IPrincipal object from HttpContext.User and checks to see whether the user is authorized to access the requested resource using the specified verb (GET, POST, and so on).

    If the user is not authorized, the UrlAuthorizationModule calls HttpApplication.CompleteRequest, which aborts normal message processing. The UrlAuthorizationModule returns an HTTP 401 status code.

  • Next, the FileAuthorizationModule is called. It checks whether the IIdentity object in HttpContext.User.Identity is an instance of the WindowsIdentity class.

    If the IIdentity object is not a WindowsIdentity, the FileAuthorizationModule performs no further processing.

    If a WindowsIdentity is present, the FileAuthorizationModule calls the AccessCheck API (through P/Invoke) to see if the authenticated caller (whose access token has been passed to ASP.NET by IIS and is exposed by the WindowsIdentity object) is authorized to access the requested file. If the file’s security descriptor contains at least a Read ACE in its DACL, the request is allowed to proceed. Otherwise the FileAuthorizationModule calls HttpApplication.CompleteRequest and returns a 401 status code.

Forms Authentication Processing

The FormsAuthenticationModule is activated when the following element is in Web.config.

<authentication mode="Forms" />

Remember that for Forms authentication, you implement the Application_Authenticate event in Global.asax. For Forms authentication, the following sequence occurs:

  • Within this code, you can construct an IPrincipal object and store it in HttpContext.User. This typically contains the role list retrieved from a custom data store (normally a SQL Server database or Active Directory). The IPrincipal object is typically an instance of theGenericPrincipal class but could also be a custom IPrincipal class.

    The FormsAuthenticationModule checks to see if you have created an IPrincipal object. If you have, it is used by the downstream authorization modules. If you haven’t, the FormsAuthenticationModule constructs a GenericPrincipal (with no roles) and stores it in the context.

    If there is no role information, any authorization checks (such as PrincipalPermssion demands) that demand role membership, will fail.

  • The UrlAuthorizationModule handles the AuthorizeRequest event. Its authorization decisions are based on the IPrincipal object contained within HttpContext.User.

Windows Authentication Processing

The WindowsAuthenticationModule is activated when the following element is in Web.config.

<authentication mode="Windows" />

For Windows authentication, the following sequence occurs:

  1. The WindowsAuthenticationModule creates a WindowsPrincipal object using the Windows access token passed to ASP.NET by IIS.

  2. It uses P/Invoke to call Win32 functions to obtain the list of Windows group that the user belongs to. These are used to populate the WindowsPrincipal role list.

  3. It stores the WindowsPrincipal object in HttpContext.User, ready to be used by the downstream authorization modules.

Event Handling

The HttpApplication object fires the set of events shown in Table 1. Individual HTTP modules can hook these events (by providing their own event handlers).

Table 1: Events fired by HttpApplication objects

Event

Notes

BeginRequest

Fired before request processing starts

AuthenticateRequest

To authenticate the caller

AuthorizeRequest

To perform access checks

ResolveRequestCache

To get a response from the cache

AcquireRequestState

To load session state

PreRequestHandlerExecute

Fired immediately before the request is sent to the handler object

PostRequestHandlerExecute

Fired immediately after the request is sent to the handler object

ReleaseRequestState

To store session state

UpdateRequestCache

To update the response cache

EndRequest

Fired after processing ends

PreSendRequestHeaders

Fired before buffered response headers are sent

PreSendRequestContent

Fired before buffered response body sent

 Note 

The HTTP handler executes in between the PreRequestHandlerExecute and PostRequestHandlerExecute events.

The last two events are non-deterministic and could occur at any time (for example, as a result of a Response.Flush). All other events are sequential.

You do not need to implement an HTTP module simply in order to hook one of these events. You can also add event handlers to Global.asax. In addition to the events listed in Table 1 (which can all be hooked by individual HTTP module objects), the HttpApplication object fires Application_OnStart and Application_OnEnd handlers, which will be familiar to ASP developers. These can be handled only within Global.asax. Finally, you can also implement custom event handlers within Global.asax for events fired by individual HTTP module objects. For example, the session state module fires Session_OnStart and Session_OnEnd events.

Implementing a Custom HTTP Module

To create your own HTTP module and insert it into the ASP.NET processing pipeline

  1. Create a class that implements IHttpModule.

  2. Place the assembly that contains the module in your application’s \bin subdirectory or you can install it into the Global Assembly Cache.

  3. Add an <HttpModules> element to your application’s web.config, as shown below.

    <system.web>  <httpModules>    <add name="modulename"         type="namespace.classname,assemblyname" />  </httpModules></system.web>

Implementing a Custom HTTP Handler

You may need to implement a custom HTTP handler, for example to handle the processing of files with the .data file extension.

To implement a custom HTTP handler

  1. Add a mapping to the IIS metabase to map the .data file extension to the ASP.NET ISAPI extension (Aspnet_isapi.dll).

    Right-click your application’s virtual directory in the IIS MMC snap-in, click the Configuration button, and then click Add to create a new mapping for .data files to C:\Winnt\Microsoft.NET\Framework\v1.0.3705\aspnet_isapi.dll.

     Note 

    If you select the Check that file exists check box when adding the mapping, then the file must be physically present. This is usually what is wanted unless you have virtualized paths that don’t map to a physical file. Virtualized paths ending with .rem or .soap are used by .NET Remoting.

  2. Create a class that implements IHttpHandler (and optionally IHttpAsyncHandler if you want to handle requests asynchronously).

  3. Place the assembly that contains the handler in your application’s \bin subdirectory or you can install it into the Global Assembly Cache.

  4. Add the handler to the processing pipeline by adding an <httpHandlers> section to your application’s Web.config file.

    <system.web>  <httpHandlers>    <add verb="*" path="*.data" type="namespace.classname, assemblyname" />  </httpHandlers></system.web>

Team LiB
Previous Section Next Section