Active Directory and ASP

ASP is the technology used in Microsoft Internet Information Services (IIS) that allows HTML pages to be created programmatically on the server. Developing an ASP application consists of creating .asp files that contain script code mixed with HTML. When a client requests an .asp file, IIS processes the script code on the server and returns HTML to the client.

ASP can work with any language that is supported by Windows Script. Traditionally, VBScript is preferred for server-side scripts, and JScript is used for client-side scripting because more browsers support it. For creating scripts on the server you can use whichever language you please. I've used VBScript in the sample for this chapter.

As with Windows Script, ASP allows you to access any COM object on the server that supports Automation—for example ActiveX Data Objects (ADO). The ability to access functionality and data on the server and return results as plain HTML is a powerful model. All the client needs to interact with the server is a modern browser. This capability makes ASP well suited for working with Active Directory.

Listings 11-1 and 11-2 show the .asp files included on the companion CD that are used to create an ASP version of the Phone sample presented in Chapter 5, "Searching Active Directory." This sample searches Active Directory for user or contact objects that match a given last name. For the objects that match, the full name and telephone number are displayed.

I've spilt the ASP version of the Phone sample into two pages. The first page, Default.asp, uses a simple form in which a user can enter the last name to look up. The second page, Results.asp, performs the search and displays the results in a table. Here is the code for the two pages:

 <%@ Language=VBScript %>
<HTML>
<HEAD>
<TITLE>Phone Number Search</TITLE>
<LINK rel="stylesheet" type="text/css" href="styles.css">
</HEAD>
<BODY>
<H1>Search for Phone Number</H1>
<FORM method=GET action="results.asp" >
<P>Enter the last name of the person to look up.</P>
<P>
    Name:
    <INPUT 
           name="Name"
           title="Enter the last name of the person to look up"
           >
    <INPUT 
           type="submit" 
           title="Search for matching names" 
           value="Search" 
           >
</P>
</FORM>
</HTML>

Listing 11-1 Default.asp asks the user for a name to search for.

 <%@ Language=VBScript %>
<HTML>
<HEAD>
<TITLE>Phone Number Search Results</TITLE>
<LINK rel="stylesheet" type="text/css" href="styles.css">
</HEAD>
<BODY>
<h1>Phone Number Search Results</h1>
<P>Search results for "<%=Request.QueryString ("Name")%>"</P>
<P><A href="default.asp">Search again</A></P>
<TABLE class=ResultsTable>
    <THEAD>
    <TR>
        <TH>Name</TH>
        <TH>Phone Number</TH></TR>
    </THEAD>
    <TBODY>
<%
` Build the query string
` First, need to discover the local global catalog server
Set adsRootDSE = GetObject("GC://RootDSE")
` Form an ADsPath string to the DN of the root of the 
` Active Directory forest 
strADsPath = "GC://" & adsRootDSE.Get("rootDomainNamingContext")
` Wrap the ADsPath with angle brackets to form the base string
strBase = "<" & strADsPath & ">"
` Release the ADSI object, no longer needed
Set adsRootDSE = Nothing
` Specify the LDAP filter
` First, indicate the category of objects to be searched 
` (all people, not just users)
strObjects = "(objectCategory=person)"
` Get the name to search for from the URL
strPerson = Request.QueryString("Name")
` If the given name is blank, then filter on all people
If (strPerson = "") Then
    strName = "(sn=*)"
Else     strName = "(sn=" & strPerson & "*)"
End If
` Add the two filters together
strFilter = "(&" & strObjects & strName & ")"
` Set the attributes for the recordset to contain
` We're interested in the common name and telephone number
strAttributes = "cn,telephoneNumber"
` Specify the scope (base, onelevel, subtree)
strScope = "subtree"
` Create ADO connection using the ADSI OLE DB provider
Set adoConnection = Server.CreateObject ("ADODB.Connection")
adoConnection.Open "Provider=ADsDSOObject;"
` Create ADO commmand object and associate with the connection
Set adoCommand = Server.CreateObject ("ADODB.Command")
adoCommand.ActiveConnection = adoConnection
` Create the command string using the four parts
adoCommand.CommandText = strBase & ";" & strFilter & ";" & _
    strAttributes & ";" & strScope
` Set the number of records in the recordset logical page
adoCommand.Properties("Page Size") = 20
` Set the maximum result size
adoCommand.Properties("Size Limit") = 20
` Sort the results based on the cn attribute
adoCommand.Properties("Sort On") = "cn"
` Execute the query for the user in the directory
Set adoRecordSet = adoCommand.Execute
If adoRecordSet.EOF Then
    Response.Write "</TBODY><THEAD><TH>No names found</TH></THEAD>"
Else     ` Loop through all the returned records
    While Not adoRecordSet.EOF
        ` Display the row using the selected fields
        Response.Write "<TR>"
        Response.Write "<TD>" & adoRecordSet.Fields("cn") & "</TD>"
        ` Check to see if telephone number field is null
        If IsNull( adoRecordSet.Fields("telephoneNumber") ) Then
            Response.Write "<TD>(number not listed)</TD>"
        Else
        ` Retrieve the telephone number and add to the display line
        Response.Write "<TD>" & _
            adoRecordSet.Fields("telephoneNumber") & "</TD>"
        End If
        ` End the row
        Response.Write "</TR>"
        ` Advance to the next record
        adoRecordSet.MoveNext
    Wend
End If
` Close the ADO connection
adoConnection.Close
%>
</TBODY>
</TABLE>
</BODY>
</HTML>

Listing 11-2 Results.asp retrieves the name to search for and uses ADO to search the directory and display matching names and telephone numbers.

As you can tell from these listings, writing VBScript for ASP pages is not much different from writing it for the Windows Script Host environment. Essentially these listings are HTML code with script code enclosed within <% %> tags. Output is generated using the Write method of the Response object. The statement <%=expression%> is a shortcut to using the Response.Write method. This statement indicates to ASP that it should evaluate the expression and output the results. The output is placed in the resulting page, which is then downloaded to the browser. In this example, the name and telephone number are displayed in an HTML table.

Figure 11-1 shows how this sample looks when hosted on a server running IIS.

Figure 11-1 ASP version of the Phone sample.

You should consider several issues when creating ASP pages, some general and others specific to ADSI and Active Directory.

  • Understand the security context. Unless authenticated, scripts processed by ASP are executed in the context of the user account specified in the IIS Web site configuration. Usually this is the IUSR_machinename account, which has limited security privileges. These security limitations can generate errors when attempting to modify Active Directory objects. I'll discuss authentication in more detail in the next section.
  • Use Server.CreateObject instead of CreateObject. While either method will work, the CreateObject method of the Server object is more efficient because with it, ASP can track the object and is aware of the threading model that the object uses. Using Server.CreateObject prevents the blocking of threads that occurs when the VBScript CreateObject function is used.
  • Minimize Context Switches. The server processes each script block within an ASP page before the page is downloaded to the client. Each script block loads and then unloads the scripting engine, a process that can be inefficient when it's required many times. Grouping server-side scripts into large blocks using the <SCRIPT RUNAT=SERVER></SCRIPT> or <% %> tags results in faster processing and less overhead on the server.

Authentication

As I mentioned earlier, the execution context for ASP pages is generally the IUSR_machinename account, where machinename is the name of the Web server. To protect itself from outside attack, this account usually has limited security privileges. In the ASP Phone sample, the security privileges for this account are not an issue because the Domain Users group (of which the IUSR_machinename account is a member) has privileges to read user and contact data. However, the ability to read the data is just a default setting. Some Active Directory configurations may have tighter security that requires higher privileges. More commonly, while reading data is allowed, changing Active Directory data is restricted to members of the appropriate administrators group or other designated accounts. In the case of displaying a user object, the person represented by that object is allowed to update his or her own personal properties.

The problem you face is figuring out which user is accessing the ASP page. The process of validating the user or client, known as authentication, allows IIS to execute ASP pages in the security context of the user or client requesting the page.

Integrated Windows Authentication

By default, IIS 5 in Windows 2000 uses anonymous authentication, which uses the IUSR_machinename security context. To force IIS to authenticate a remote user securely, you set the properties for the Web site (or directory or page) in the Authentication Methods dialog box for IIS Web site properties. Clear the Anonymous Access check box and select the Integrated Windows Authentication check box, as shown in Figure 11-2.

Figure 11-2 Using Integrated Windows authentication for Web sites.

Integrated Windows authentication was previously known as NT LAN Manager (NTLM) and Windows NT Challenge/Response authentication. Windows 2000 and IIS 5 support both NTLM Challenge/Response authentication and the native Kerberos v5 security protocol. Incorporating Kerberos is easier and has the added advantage of verifying the server to the client to ensure the server is not being impersonated.

Figure 11-3 shows an overview of the steps involved with Web authentication using NTLM Challenge/Response.

Figure 11-3 Web authentication using NTLM Challenge/Response.

First the browser client makes a request for a resource such as a Web page. The request is made as an HTTP GET request. If the resource is restricted and requires authentication, the Web server returns an HTTP error response to the browser. In this case, a 401 Access Denied response is sent along with two HTTP header packets—one package is a negotiate request, and the other is an NTLM challenge header. The browser creates a response on the basis of the supported authentication methods and the challenge. The response includes the credentials of the current user, but it does not include the user's password. This means that anyone sniffing the network packets cannot gain access to the actual password. This response is included in another HTTP GET request. The server processes the request and authenticates the response. If the credentials of the user allow access to the selected resource, the HTTP request is accepted and the page is returned to the browser. If the user does not have access, a 403 error response is returned to the browser, which means the credentials were valid but not sufficient to allow access. Depending on the browser, a password dialog box might be displayed to the user, as shown in Figure 11-4.

Figure 11-4 Enter Network Password dialog box.

Integrated Windows authentication has some limitations, namely that only Microsoft Internet Explorer supports it. Also, it cannot be used when a firewall or proxy server re-creates the HTTP headers because to do so would compromise the security of the authentication. For corporate intranets, re-creating HTTP headers is generally not a problem, but when creating ADSI applications for use outside a corporate network, other methods must be used.


Introduction to Kerberos

Windows 2000 introduced a new security protocol to the Windows family, Kerberos. Originally developed at the Massachusetts Institute of Technology and defined in RFC 1510 and RFC 1964, Kerberos is the default authentication protocol for Windows 2000 workstations and servers. Windows 2000 implements version 5 of Kerberos.

A notable difference between the Kerberos and NTLM protocols (also supported in Windows 2000) is the concept of mutual authentication. With NTLM, the client application sends the user's credentials to the server. If the credentials match what's stored in the security database (Active Directory in Windows 2000, or the Security Accounts Manger in Windows NT 4.0), the user is authenticated. Thus, the server "knows" who the client is, but the client does not know who the server is. A rouge server could request credentials from the user and retain them for future malicious use. With mutual authentication under Kerberos, the server must authenticate itself to the client before the client presents the user's credentials.

Electronic security works best when it's kept simple. Simplicity provides fewer weak spots to exploit. Kerberos works on a simple "ticket" scheme. When a client presents credentials to the authentication service (AS) running on a Windows 2000 domain controller, the AS verifies the credentials with Active Directory. If they match, the AS sends a ticket back to the client. A ticket is just a packet of data that the Kerberos subsystems understand. The ticket contains, among other things, the client's identity (not the credentials, however), a session key, and a timestamp. All the sensitive parts of a ticket are encrypted with the server's key.

The first ticket issued by the AS is a special ticket, known as the ticket granting ticket (TGT). This ticket is used to access the Key Distribution Center (KDC). The KDC is another security subsystem of Windows 2000. Its role is to validate access to the services available on the server and supply cryptography keys to clients to secure their communications.

After the client has been authenticated by the server and holds a TGT, it can then submit that ticket to the KDC when it wants to access a secure service, such as IIS on another server. When the KDC gets the service request and TGT from the client, it issues a service ticket (ST) that contains a session key. The ST is sort of a "hall pass" that allows the client to validate itself to the service on another server. Service tickets can expire, in which case the client asks the KDC to issue a new ticket.

The client presents the ST to IIS and, in return, IIS sends back an authentication packet that is used by the client to validate the service. Then the client can communicate with the service normally—in this case issuing HTTP requests. The Kerberos Tray tool, part of the Microsoft Windows 2000 Server Resource Kit, is useful for viewing what tickets the current client holds. Here's an example of Kerberos Tray.


Basic Authentication

Windows 2000 and IIS 5 support Basic authentication as another way to validate a user. This method uses the HTTP header to send the user name and password to the server for validation. Most Web browsers support Basic authentication as part of the HTTP protocol defined in RFC 2617. The password is encoded using the simple binary BASE64 encoding scheme. While not exactly readable, this scheme is easy to decode by someone trying to get at your password. As such, Windows 2000 considers the password to be sent in "clear text," which can be dangerous if compromised.

By combining Basic authentication with the Secure Sockets Layer (SSL) and the Transport Layer Security (TLS) protocols, you can achieve a moderate degree of protection. Nonetheless, there are issues with Basic authentication and site design resulting in the browser continuing to send the clear text password after the initial authentication without using the SSL channel for protection. Because the integrity of the account password is vital to Windows security, I can't recommend Basic authentication, particularly when more secure methods exists.

COM+ Components

Sometimes, regardless of who is requesting an operation, you need to execute a script in a high-level security context. Operations such as creating or deleting users require Administrator access by default. Instead of assigning permissions to users to perform restricted operations, you can create a COM+ component with high-level access on the Web server to work on behalf of the user.

COM+ allows developers to partition their application into components and give each its own security context in a transaction managed environment on a server. By encapsulating the functionality of the application into a component, you can instruct Windows to execute the component using impersonation. The component is registered with COM+ and given a user account and password that's used only to execute that component. The ASP page creates an instance of the component and uses it to access directory data. Using a component like this is handy when you need to circumvent the built-in security in an isolated fashion.

For example, you could create a COM+ component that allows the creation of computer accounts over an intranet application. When someone needs to add a new computer to the forest, he or she could use a Web site that asks for the computer account name and offers to reset an existing account or add a new one. Because the user might be using an older operating system to make the request (after all, they are creating a new computer account!), secure forms of authentication may not be available.

The solution would be to take the program that creates or resets computer accounts and add it as a COM+ component to the Web server that provides the interface. The COM+ application is assigned to a user account with sufficient rights to create or reset computer accounts. The ASP code can then reference the component, passing it the computer name and other information provided by the user and returning the status of the operation when complete.

The Domain Admins group by default is allowed to create computer accounts and many other tasks in Active Directory. Assigning a high level of access to a process that only creates computer accounts is probably overkill, and the application might intentionally, or unintentionally, wreak havoc. A better solution is to create a specific user account named Computer Accounts Manager and give that account only the rights necessary to create and reset computer accounts. Use that account and its password when setting up the COM+ application.

You'll rarely need to create a COM+ component. Through delegation and careful security planning, it's usually not necessary to impersonate high-level accounts to perform directory operations. Understanding and using the built-in security features of Windows will meet most requirements.

While I'd like to cover all the many cool and interesting things that ASP and COM+ offer developers of directory-enabled applications, I can't do so and still publish this book in a reasonable time frame. A book that I've found useful is Alex Homer's Professional ASP 3.0 Web Techniques by (guess who) Alex Homer (WROX, 2000). Another good source of information is Designing Secure Web-Based Applications for Microsoft Windows 2000 by Michael Howard (Microsoft Press, 2000). This book is particularly helpful for understanding the issues of security and authentication for Web-based ADSI applications.



MicrosoftR WindowsR 2000 Active DirectoryT Programming
MicrosoftR WindowsR 2000 Active DirectoryT Programming
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 108

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net