Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
546,23 KB
Nội dung
Although the compilation settings allow us to control how the application is compiled, they do not allow us to control how the application is run. To control the identity of the process that ASP.NET uses for compiling, processing, and servicing requests of our ASP.NET application, we have the identity settings. Controlling the Identity of Execution We can use the <identity> setting of machine.config (note that identity can be set in web.config files as well) to define which Windows user to impersonate when making requests from the operating system. This is separate from the trust level assigned to a particular application. The trust level, set in the configuration system for an application, determines what a particular application may or may not do. Trust levels are used to sandbox applications. We have three attributes used with <identity>: impersonate - The impersonate attribute of <identity> is a Boolean value that determines the Windows NT user the ASP.NET worker process runs under. If impersonate="true", ASP.NET will run under the identity provided by IIS. If set to true, this would be IUSR[server name], or whatever identity that IIS is configured to impersonate. However, if Windows NT authentication is enabled on the web server, ASP.NET will impersonate the authenticated user. Alternatively, we can name a Windows NT user and password for the ASP.NET process to run as. The default setting of impersonate is False. userName - Available when impersonate="true", the name value names a valid Windows NT account to impersonate. password - Complementary to name, the password of the user to impersonate. As mentioned above, the default setting is impersonate="false". Let's look at some examples where ASP.NET runs with impersonate="true" allowing the impersonation to flow from IIS, as well as configuring the user/password for ASP.NET to run as. Impersonating the IIS User To impersonate the user that IIS uses, we first need to set impersonate="true": <configuration> <system.web> <identity impersonate="true" /> </system.web> </configuration> To test impersonation, we can use the following ASP.NET page, written in Visual Basic .NET: <%@ Import Namespace="System.Security.Principal" %> <Script runat="server"> Public Sub Page_Load(sender As Object, e As EventArgs) lblIdentity.Text = WindowsIdentity.GetCurrent().Name End Sub </Script> Current identity is: <asp:label id="lblIdentity" runat="server" /> This code simply uses the WindowsIdentity class's GetCurrent() method to return the name of the Windows user the request is processed as. On my server, when impersonate="false" the result of a request to this page is: Current identity is: NT AUTHORITY\SYSTEM When impersonate="true" the result is: Current identity is: RHOWARD-LAPTOP\IUSR_RHOWARD-LAPTOP ASP.NET is impersonating the Windows user that IIS is using to process the request. In the above case, this is the IUSR_[machine name] Windows account that IIS uses for anonymous requests. If we configured IIS to use a different anonymous account, or enabled IIS security to support NTLM authentication, we would see a different result. For example, if we enable NTLM authentication for the server (see Chapter 14 for details on NTLM authentication), when I run the code I see: Since NTLM authentication is enabled, as is impersonation with ASP.NET, ASP.NET impersonates the Windows users that IIS NTLM authenticates. In this case, the user RHOWARD in the domain REDMOND. The last option we can configure with identity is to explicitly name a username and password. Note that the username and password values are stored in clear text in the configuration system: <configuration> <system.web> <identity impersonate="true" username="ASPNET_Anonymous" password="93%dk12" /> </system.web> </configuration> In the above example we've identified a user ASPNET_Anonymous as the user for ASP.NET to impersonate. Keep in mind that the user impersonated needs to have the necessary file access permissions, in other words ASPNET_Anonymous needs to have access to the necessary ASP.NET files and common directory paths. Please see the next chapter for more details on ASP.NET security. Controlling the identity of the impersonation account used by ASP.NET allows us to have granular system-level control over what any particular user may or may not do. However, we also have to provide the impersonation account with the appropriate levels of access to be able to accomplish meaningful work in our system. Extending ASP.NET with HTTP Handlers ASP.NET builds upon an extensible architecture known simply as the HTTP runtime. The runtime is responsible for handling requests and sending responses. It is up to individual handlers, such as an ASP.NET page or web service, to implement the work to be done on a request. Much as IIS supports a low-level API, known as ISAPI, for letting developers implement custom solutions, such as building a JSP implementation that runs on IIS, ASP.NET implements a similar concept with HTTP Handlers. A request is assigned to ASP.NET from IIS, ASP.NET then examines entries in the <httpHandlers> section, based on the extension, .aspx for example, of the request to determine which handler the request should be routed to. The most common entry used is the .aspx extension. Below is the entry in machine.config for the HTTP Handler used for the .aspx extension (as well as several other familiar extensions): <configuration> <system.web> <httpHandlers> <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory,System.Web" /> <add verb="*" path="*.asmx" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services" validate="false"/> <add verb="*" path="*.ascx" type="System.Web.HttpForbiddenHandler,System.Web" /> <add verb="*" path="*.config" type="System.Web.HttpForbiddenHandler,System.Web" /> </httpHandlers> </system.web> </configuration> In the above configuration code, four common handlers are identified (note, the actual machine.config file identifies about 18 entries). We have the HTTP handlers for pages ( .aspx), web services (.asmx), user controls (.ascx), and configuration ( .config). Both page and web services map to actual classes, while user controls and configuration map to a special handler called HttpForbiddenHandler. This handler explicitly denies access to these extensions when requested directly, so a request for Address.ascx or web.config will send back an access denied reply. As mentioned above, HTTP Handlers are the ASP.NET equivalent of IIS ISAPI extensions. However, unlike ISAPI, which was only accessible to developers who could code C++, HTTP Handlers can be coded in any .NET language - Visual Basic .NET developers can now author the equivalent of an ISAPI extension. Let's look at a simple HTTP Handler written in Visual Basic .NET: Imports System Imports System.Web Public Class HelloWorldHandler Implements IHttpHandler Sub ProcessRequest(ByVal context As HttpContext) _ Implements IHttpHandler.ProcessRequest Dim Request As HttpRequest = context.Request Dim Response As HttpResponse = context.Response Response.Write("<html>") Response.Write("<body>") Response.Write("<h1> Hello " + _ Request.QueryString("Name") + "</h1>") Response.Write("</body>") Response.Write("</html>") End Sub Public ReadOnly Property IsReusable As Boolean _ Implements IHttpHandler.IsReusable Get Return True End Get End Property End Class Above, we have written a Visual Basic .NET class, HelloWorldHandler, that implements the IHttpHandler interface. This interface requires that we implement a single method, ProcessRequest(), as well as a single property, IsReusable. Within the ProcessRequest() method, which is responsible for processing the request, we Response.Write() some simple HTML. Within the body of the HTML we use the Request to access the Name parameter passed on the query string. To register this handler, we first must build it using either the command line compilers or Visual Studio .NET. We then can deploy the compiled .dll file to an ASP.NET bin directory and add the entry into our configuration file (in this particular case we are using a web.config file). We use the <add> tag of <httpHandlers>. Adding Handlers The <add> tag is used to name a class that implements either the IHttpHandler or the IHttpHandlerFactory interface. All HTTP Handlers must implement one of these two interfaces so that the HTTP runtime knows how to call them. Below is the format that we use for this tag: <configuration> <system.web> <httpHandlers> <add verb="[HTTP Verb]" path="[Request Path]" type="[.NET Class]"/> </httpHandlers> </system.web> </configuration> There are three attributes within the <add> tag that tell ASP.NET how the HTTP Handler is to be interpreted: verb - The verb attribute instructs the HTTP runtime about the HTTP verb type that the handler services request. Values for the verb attribute include asterisks (*), which instructs the HTTP runtime to match on all HTTP verbs, or a string value that names an HTTP verb. For example, the HTTP Get verb, verb="Get", or a string value of semi-colon separated HTTP verbs. For example, verb="Get; Post; Head". path - The path attribute instructs the HTTP runtime as to the request path, for example /MyApp/test.aspx, that this HTTP Handler is executed for. Valid values for the path include asterisks (*) with an extension ( *.aspx), which instruct the HTTP runtime to match only resources that match the extension, or a string value with an extension. We can name one resource that maps to an HTTP Handler. A good example here is the Trace.axd HTTP Handler, which uses the path value of path="trace.axd". type - The type attribute names the .NET class that implements the HTTP Handler code. The value for type follows the format [Namespace].[Class], [Assembly name]. If we compile the above sample, HelloWorldHandler.vb, to an assembly named Simple.dll, we could make the following entry in a configuration file: <configuration> <system.web> <httpHandlers> <add verb="*" path="HelloWorld.aspx" type="HelloWorldHandler, Simple"/> </httpHandlers> </system.web> </configuration> The above configuration entry names an assembly, Simple, that contains a class HelloWorldHandler. ASP.NET will assume that HelloWorldHandler implements the IHttpHandler interface. We then identify the path and verb that the ASP.NET HTTP runtime uses to route to this handler. In this case, we have told the HTTP runtime that we wish to route on all verbs (via the *) and that we will service requests for HelloWorld.aspx. We could use a custom extension, such as *.wrox, but this would further require us to map this .wrox extension to ASP.NET in ISS Manager - as we discussed in the previous chapter. We are now ready to service requests for this handler. If we open a web browser, and point it to the web application that contains bin\Simple.dll as well as the above web.config file that we defined, we can make a request for /HelloWorld.aspx?Name=Rob: ASP.NET maps the request HelloWorld.aspx to the HTTP Handler we built called Simple.dll. The result is that the HTTP Handler is executed and our request is served. This is a somewhat simple example, but it is easy to envision the types of applications that could be created. What if this HTTP Handler was declared in machine.config, and we decided that we didn't want a given application to have access to it? In that case, we can use the <remove> tag of the <httpHandlers> section. Removing Handlers The <remove> tag can be used to override <add> entries that are either inherited or declared within the same configuration file. This is useful for removing HTTP Handlers from some web applications, or commenting out HTTP Handlers so that the functionality is unavailable to end users: <remove verb="[http verb | *]" path="[path]"/> A good example is the trace.axd HTTP Handler used for tracing, which we may decide not to support in all of our web applications. machine.config defines the following entry for the trace.axd: <configuration> <system.web> <httpHandlers> <add verb="*" path="trace.axd" type="System.Web.Handlers.TraceHandler,System.Web" /> </httpHandlers> </system.web> </configuration> We could remove support of this handler in web applications by creating a web.config file and making the following entry using the <remove> tag: <configuration> <system.web> <httpHandlers> <remove verb="*" path="trace.axd"/> </httpHandlers> </system.web> </configuration> The web application using the above web.config file will generate a file not found error when a request is made for trace.axd. HTTP Handlers allow us, at a low-level, to handle the application request. We can build a simple example, such as the HelloWorld example above, or we could write more complex examples that take over well-known extensions such as .jpg to add additional functionality, so for example, a request for chart.jpg?x=10&y =13 could draw a graph. The opportunities are endless! However, what happens in the case where we simply want to look at the request? Rather than replace the functionality that ASP.NET pages provide us with, we simply want to examine the request before or after the HTTP Handler processes it. For this we have HTTP Modules. Extending ASP.NET with HTTP Modules Whereas HTTP Handlers allow us to map a request to a specific class to handle the request, HTTP Modules act as filters (note that HTTP Modules are similar in function to ISAPI filters) that we can apply before the handler sees the request or after the handler is done with the request. ASP.NET makes use of modules for cookieless session state, output caching, and several security-related features. In the Advanced Topics discussion in Chapter 20, we will look at an HTTP Mod ule that authenticates web service requests. Before the request is 'handled' by the appropriate .asmx file, our HTTP Module looks at the request, determines if it is a SOAP message, and if it is a SOAP message, it extracts out the username and password values from the SOAP header. As it relates to configuration, we have the same three settings as we found for HTTP Handlers; <add>, <remove>, and <clear>. <add> is the only tag that differs from HTTP Handlers. Adding Modules The <add> entry for <httpModules> simply names the module and references the class that implements the IHttpModule interface and the assembly the class exists within. Just as HTTP Handlers implement a common interface, IHttpHandler, we have an interface that modules implement. [...]... is not servicing requests! ASP.NET, on the other hand, was designed to take into account the errors that can and will occur within the system Rather than running in process with IIS, ASP.NET runs in a separate worker process, aspnet_wp.exe ASP.NET uses IIS only to receive requests and to send responses (as a request/response broker) IIS is not executing any ASP.NET code The ASP.NET process can come and... process can come and go, and it doesn't affect the stability of IIS in any way We can view the ASP.NET process (aspnet_wp.exe) through the Windows Task Manager after a request for an ASP.NET resource has been made, as the process starts when ASP.NET applications are being used To view the process, first request an ASP.NET resource and then open up the Windows Task Manager (press Control-Shift-Escape simultaneously)... two we just examined Another of the configuration options found in machine.config is the process model setting The process model settings allow us to configure the ASP.NET Worker Process Configuring the ASP.NET Worker Process Unlike ASP, ASP.NET runs in a separate process from IIS When code misbehaved in ASP-say we forgot to free memory in a COM object - the leak could degrade the server performance... and memory usage in KB The section of machine.config is used to configure ASP.NET process management These settings can only be made in machine.config, as they apply to all ASP.NET applications on that machine Within the settings, we can configure options such as which processor each ASP.NET worker process should affinitize with, and we can additionally configure settings... amount of time Below is the default machine.config settings: Note, an important but subtle change in the final released version of ASP.NET is the Windows identity that the ASP.NET worker process runs as In previous beta versions it was the 慡 ystem?account The final version uses a special Windows account created when the NET Framework is installed: aspnet For more details on the implications of these changes... can take this example a step further and show the requestLimit being enforced by ASP.NET If we: Set the requestLimit to 5 Save our machine.config file Open the Windows Task Manager, view the aspnet_wp.exe process, and take note of the process ID Next, if we make more than five requests for an ASP.NET application file, ASP.NET will recycle the process To see this go back and check the process ID of... can service requests A new option that ASP.NET now supports is a web garden, in other words multiple processes on the same server A web garden lets us host multiple ASP.NET worker processes on a single server, thus providing the application with better hardware scalability Web garden mode is only supported on multi-processor servers To support a web garden with ASP.NET, we use two inter-related ... threads used by the ASP.NET worker process: maxWorkerThreads - The maximum number of threads that exist within the thread pool of an ASP.NET worker process The default is 25 Note that this does not mean that 25 threads exist at all time Rather, the thread pool dynamically manages the size of the threads available maxIoThreads - The maximum number of I/O threads that exist within the ASP.NET worker process... shut itself down gracefully before ASP.NET calls the kill command on the process- kill is a low-level command that forcefully removes the process By default, shutDownTimeout is set to five seconds, but this is configurable: shutDownTimeout = "[HH:MM:SS]" This is a very useful configuration setting for processes that have crossed some threshold and appear to have crashed ASP.NET can kill the process after... allows us to configure ASP.NET to recycle after a certain number of requests are served The default value is Infinite, no request limit, but we can also set it to a number: requestLimit = "[Infinite | int]" If we notice that the performance of our application degrades after a certain number of requests, for example 5000, we can configure the requestLimit property to a threshold of 5000 ASP.NET will then . certain number of requests, for example 500 0, we can configure the requestLimit property to a threshold of 500 0. ASP. NET will then recycle the process after 500 0 requests. We can take this example. comImpersonationLevel="Impersonate" responseRestartDeadlockInterval=" ;00 :09 :00 " responseDeadlockInterval=" ;00 :03 :00 " maxWorkerThreads="25" maxIoThreads="25". shutdownTimeout=" ;0: 00: 05" requestLimit="Infinite" requestQueueLimit=" 500 0" restartQueueLimit=" ; 10 " memoryLimit=" 60& quot; webGarden="false"