|only for RuBoard - do not distribute or recompile|
The HTTP standard provides support to authenticate and authorize user access. When a browser sends an HTTP request for a resource that requires authentication, a server can challenge the request by sending a response with the status code of 401 Unauthorized. When an unauthorized response is received, the browser presents a dialog box that collects a username and password; a dialog box presented by Netscape is shown in Figure 9-1. After the username and password have been entered, the browser then resends the request containing an extra header field that encodes the user credentials.
This support doesn't authenticate a user or provide authorization to access a resource or service. The server needs the encoded username and password to establish the user's credentials and then decide if the user is authorized to receive the requested resource. How the server performs the authentication depends on the application. An Apache server, configured to protect resources with authentication, uses a file that contains a list of usernames and encrypted passwords, while other applications might use a table of users in a database.
Figure 9-2 shows the interaction between a web browser and a web server when a request is challenged The browser sends a request for a resource stored on the server. The server sends back a challenge response with the status code set to 401 Unauthorized, and the header field WWW-Authenticate. The WWW-Authenticate field contains parameters that instruct the browser on how to meet the challenge. The browser may need to prompt for a username and password to meet the challenge. The browser then resends the request, including the Authorization header field that contains the credentials the server requires.
Example 9-1 shows the HTTP response sent from an Apache server when a request is made for a resource that requires authentication.
HTTP/1.1 401 Authorization Required Date: Mon, 21 May 2001 23:40:54 GMT Server: Apache/1.3.19 (Unix) PHP/4.0.5 WWW-Authenticate: Basic realm="Marketing Secret" Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD> <TITLE>401 Authorization Required</TITLE> </HEAD><BODY> <H1>Authorization Required</H1> This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.<P> <HR> <ADDRESS>Apache/1.3.19 Server at dexter Port 80</ADDRESS> </BODY></HTML>
The WWW-Authenticate header field contains the challenge method, the method by which the browser collects and encodes the user credentials. In the example the method is set to Basic. The header field also contains the name of the realm the authentication applies to.
The realm is used by the browser to label usernames and passwords and is displayed when credentials are collected; Figure 9-1 shows the realm Marketing Secret. A browser can automatically respond to a challenge if the browser has previously collected credentials for the realm. The browser stores authentication credentials for each realm it encounters until the browser program is terminated. Once the browser has collected the credentials, it resends the original request with the additional Authorization header field. Example 9-2 shows a request containing encoded credentials in the Authorization header field.
GET /auth/keys.php HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/4.51 [en] (WinNT; I) Host: localhost Accept: image/gif, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 Authorization: Basic ZGF2ZTpwbGF0eXB1cw==
The Basic encoding is just that: basic! The string that is encoded into the Authorization header field is simply the username and the password separated by a colon character and then base-64 encoded. Base-64 encoding isn't designed to protect data; rather it allows binary data to be transmitted over a network, and therefore provides no real protection of the username and password. The Basic encoding of the credentials provides protection from casual inspection only.
Some web servers, including Apache, support the Digest encoding method. The Digest method is more secure than the Basic method because the password isn't sent over the network. When the Digest method is used, the server generates a random string to send with the authorization challenge. The browser then encrypts the random string using the password provided by the user as an encryption key. The encrypted string is sent back to the server in the Authorization header field, as the resource is rerequested. The server uses a copy of the password stored at the server to encrypt the same random string and compares it to the encrypted string that has just arrived. If they match, the server has authenticated the user. The advantage is that only the encrypted random string is exchanged, not the user password.
Both the web server and the browser need to support the Digest encoding method. Unfortunately, most browsers support only Basic. Microsoft has developed a proprietary method for use with HTTP authentication called NTLM that is supported only by Internet Explorer and Microsoft's IIS web server.
While the Basic encoding method provides no real security, the Secure Sockets Layer (SSL) protocol can protect the HTTP requests and responses sent between browsers and servers. Because of SSL, there is little pressure on browser builders to implement more secure schemes. For web database applications that transmit sensitive information, such as passwords, we recommend SSL be used. We discuss SSL later in this chapter.
The simplest method to restrict access to an application is to use the Apache authentication support. The Apache server can easily be configured to use HTTP authentication to protect the resources it serves. Apache allows authentication to be set up on a directory-by-directory basis by adding parameters to the Directory setting in the httpd.conf configuration file. The following example shows part of an httpd.conf file that protects the resources—HTML files, PHP scripts, images, and so on—stored in the /usr/local/apache/htdocs/auth directory:
# Set up an authenticated directory <Directory "/usr/local/apache/htdocs/auth"> AuthType Basic AuthName "Secret Mens Business" AuthUserFile /usr/local/apache/allow.users require hugh, dave, jim </Directory>
If PHP scripts and other sensitive resources are placed within a protected directory, a user can access the application only by first passing the Apache authentication. The Apache server responds with a challenge to unauthorized requests for any resources in the protected directory. The AuthType is set to Basic to indicate the method that encodes the username and password collected from the browser, and the AuthName is set to the name of the realm. Apache authorizes users who are listed in the require setting by checking the username and password against those held in the AuthUserFile. There are other parameters that aren't discussed here; you should refer to the Apache references listed in Appendix E for full configuration details.
For simple web database applications, Apache authentication provides a suitable solution. When usernames and passwords need to be checked against a database or some other source, or when HTTP authentication can't meet the needs of the application, authentication can be managed by PHP. The next section describes how PHP can manage HTTP authentication directly without configuring Apache. Later, in Section 9.4, we describe how to provide authentication without using HTTP authentication support.
|only for RuBoard - do not distribute or recompile|