Chapter 9. Authentication and Security
There are many database applications in which restrictions need to be applied to control user access. Some applications deal with sensitive information such as bank account details, while others provide information or services only to paying customers. These applications need to authenticate and authorize user requests, typically by collecting a username and password, and checking these against a list of valid users. As well as authenticating those who have access to a service, web applications often need to protect the data that is transmitted over the Internet from those who shouldn't see it.
In this chapter we discuss the techniques used to build web database applications that authenticate, authorize, and protect the data that is transmitted over the Web. The topics covered in this chapter include:
9.1. HTTP Authentication
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.
Figure 9-1. Netscape requests a username and password
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.
9.1.1. How HTTP Authentication Works
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.
Figure 9-2. The sequence of HTTP requests and responses when an unauthorized page is requested
Example 9-1. An unauthorized response sent by Apache
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.
Example 9-2. An authorized request sent by the browser after the credentials have been collected
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.
9.1.2. Using Apache to Authenticate
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.
Copyright © 2003 O'Reilly & Associates. All rights reserved.