HTTP

Authentication

Authentication, Authorization and Access Control

Authentication is the process of verifying "someone is who he claims he is". In other words, authentication is to ascertain the identity of the users. This is usually carried out via a credential (username/password). Other techniques include smart card and biometrics (retina scan, voice recognition, or fingerprints).

Authorization followed authentication. Once the identity of the user is ascertained, the authorization process decides whether this client has the authority to access the requested resources. The criteria may include whether the client possesses the necessary authority (e.g., manager or worker has different authorities) or whether he has paid the admission or subscription.

Access control is a much more general way of controlling access to a resource. Access control is not limited to checking the identify of the client, it could include other criteria, such as the network address and hostname, the time of day, the type of browser which the client is using, the referrer, and etc. Apache provides a rich set of directives for controlling access to directories, files, and locations, e.g., <Directory>, <File>, <Location>, Allow, Deny, Order, and .htaccess (refer to Apache How-To: Access Control).

This section describes the identity-based access control, i.e., authentication and authorization. In Apache, authentication and authorization are inextricable and are configured together.

HTTP provides two schemes for authenticating clients: Basic Access Authentication and Digest Access Authentication. The specification is given in "RFC 2617 HTTP Authentication: Basic and Digest Access Authentication". It is important to stress that these schemes merely provide a mean for the client to send in his username/password for authentication. The schemes do not ensure message confidentially (i.e., message encryption), message integrity (man-in-the-middle attack), and non-repudiation. For high-risk and high-security systems which require these guarantees, you have to turn to SSL (Secure Socket Layout). HTTP with SSL (or HTTPS) will be discussed in the later chapter.

Basic Authentication

Basic Access Authentication scheme was introduced since HTTP/1.0. It is a simple scheme, which uses username/password to authenticate clients.

The client sends his username and password to the server. The server looks up the password file and decide whether the client is authorized to access the requested resource. The password file can be a simple text file, or a database (which greatly improves the retrieval and matching process for large user base). Users can be grouped into groups. Access can then be controlled at the group level. To improve on the flexibility, the protected space is divided into realm. Each username/password pair is valid for one particular realm.

CAUTION: The Basic Access Authentication scheme is not considered secure nor safe. This is because the username, password, and messages are all sent in clear text (i.e., not encrypted). Eavesdroppers or network snifters can easily pick up your username, password, and the messages. You should be extremely cautious when giving your username and password to a server that uses basic authentication scheme (if you use the same password to access your bank account!?). Use a dedicated "low-risk" password for this site instead. (The morale of this story is you should use different passwords for different purposes, although it could be hard to manage.)

Implementing the Basic Access Authentication Scheme

The configuration for basic access authentication involves 3 steps:

  1. Create a password file.
  2. Configure the Apache server to use this password file.
  3. Optionally, use a group file to group related users and control access on the group basis.

Step 1: To create the password file, use the utility "htpasswd.exe" distributed with Apache HTTP Server (in directory "%APACHE_HOME%\bin") as shown below:

> ... change directory to %APACHE_HOME\bin ...
> htpasswd ?
(The help menu)
 
> htpasswd -c ../conf/basic.users bob
(Option -c is used to create a new file)
Automatically using MD5 format on Windows.
New password: ***
Re-type new password: ***
Adding password for user bob
 
> htpasswd ../conf/basic.users bill
Automatically using MD5 format on Windows.
New password: ****
Re-type new password: ****
Adding password for user bill
 
> htpasswd ../conf/basic.users alice
Automatically using MD5 format on Windows.
New password: *****
Re-type new password: *****
Adding password for user alice
 
> htpasswd ../conf/basic.users alan
Automatically using MD5 format on Windows.
New password: ****
Re-type new password: ****
Adding password for user alan

The above commands create a user file called "basic.users" in "%APACHE_HOME\conf"; followed by 4 users (with password). Make sure that this user file is outside the document directory and is protected from unauthorized persons. If you open this user file, you shall see that the digest of the passwords are stored, instead of the passwords in clear text:

bob:$apr1$c0Nw/XQI$mLuIl7DboHBkp4tZfh2Uj/
bill:$apr1$vn.O35Db$t8UasLOGIjBgVE93UvIMh0
alice:$apr1$1rPtsZaD$0MpAqMQC.KpePAffgnqK70
alan:$apr1$1pPU8Nwf$Ms/1EO90PBm25pnvaT5bi0

Step 2: To configure Apache HTTP server to use the password file we have just created, add the following directives into the appropriate <directory> of the configuration file "%APACHE_HOME%\conf\httpd.conf" (or place them inside the ".htaccess" of the directory to be protected if override is permitted).

<Directory protected-directories>
  AuthType Basic
  AuthName Private
  AuthUserFile conf/basic.users
  Require valid-user
</Directory>

When a client requests for a protected resource, Apache replies with a "401 Authentication Required" response. This is to inform the client that user credential is needed. Upon receiving the 401 response, the browser will prompt the user to supply his username/password, and send them to the server for verification.

Since HTTP is a stateless protocol, every request will be treated on its own, without knowledge of the previous requests. That is to say, you have to supply the same username/password to every protected resource requested. Fortunately, the browser takes care of the details by caching the username, password, realm and server name, so that you do not have to type in your username/password for every request.

The authentication process is summarized as follows:

  1. A client requests for a web resource, which is protected under the basic access authentication scheme, via an HTTP GET request.
  2. The server returns a "401 Authorization Required" response. The 401 response includes a "WWW-Authenticate" response header, specifying the type of authentication scheme and the realm that the protected resource belongs to.
  3. The client re-submits the HTTP GET request with an "Authorization" request header, which gives the credential (username/password) needed to access that realm. The credential is usually cached by the browser for all subsequent requests to the same realm of that particular server.
  4. Server checks the credential. If it is acceptable, the server returns the requested resource with a "200 OK" status code. Otherwise, a "401 Authorization Required" response will be sent again. Most browsers will repeat step (2) to (4) for 3 times, before displaying the 401 message. The browser will display 401 message if the user cancels the request.

Message Trace

Let's look at a trace of messages under Basic Access Authentication. I have created a directory called "basic_auth" (under "htdocs"), which contains a "test.html" file. Assuming that Apache HTTP Server is running on port 8000.

Security Exposure

In basic access authentication, the credential client sends to the server is not encrypted but simply Base64-encoded (refer to RFC2045 for specification on Base64 encoding). If you look up the Base64 table (or use WinZip), you will see the username/password in the Authorization header in clear text.

The most serious flaw in basic access authentication is that it transmits the password in clear text over the network. Hence, this password should not be the same as the one you use to access your bank account. Furthermore, once authenticated, the message is also sent in clear text. The username, password, and the message are subjected to network sniffing.

User Group

Step 3: Optionally, you can group the users into groups, and grant access to selected groups. To use group access control, you have to create a "Group File" (save as "%APACHE_HOME%/conf/basic.groups").

manager: alice alan
worker: bob bill

In the Apache's configuration "conf\httpd.conf", include the following directives:

<Directory protected-directories>
  AuthType Basic
  AuthName Private
  AuthUserFile conf/basic.users
  AuthGroupFile conf/basic.groups
  Require group manager
</Directory>

Configuration Directives

Refer to Apache documentation @ "%APACHE_HOME%\htdocs\manual\mod\mod_auth.html" for details on the configuration directives.

AuthType: selects the type of user authentication. Only Basic and Digest are currently implemented.

AuthType Basic|Digest

AuthUserFile: specifies the name of the password file, which can be created using htpasswd utility. Each line of the user file contains a username followed by a colon, followed by the crypt() encrypted password (or MD5-digested password).

AuthUserFile user-filename

AuthGroupFile: specifies the name of the group file. Each line of the group file contains a group name followed by a colon, followed by the members' username separated by a space.

AuthGroupFile group-filename

Require: specifies which authenticated users can access the protected resource.

Require entity-name-1 [entity-name-2] ...

Access controls are effective for all HTTP request methods (GET, POST etc) used to request the resource. If you wish to apply access controls only to specific methods (e.g., POST but not GET), you can place the Require directive inside a <Limit> or <LimitExcept> section.

Satisfy: set the access policy if both Allow (for access control) and Require (for authentication) directives are used. It takes value of either all (default) or any. This directive is only useful if access to aparticular realm is being restricted by both username/password and client host address. In this case the default behavior of "all" requires the client passes the address access restriction and provided a valid username/password. With the "any" option, the client will be granted access if he either passes the host restriction or provide a valid username/password. This can be used to password restrict an area, but to let clients from particular addresses in without prompting for a password.

Satisfy all|any

Digest Access Authentication

Like basic access authentication, digest access authentication requires a client to supply his credential, in terms of username and password. Unlike basic access authentication, digest access authentication does not send the password over the network in clear text. Instead, the MD5 digest of the password is transmitted (hence, the name digest access authentication). Network snifters cannot recover your password from the digest.

(A digest is a hash value from a one-way hash function. Suppose that y is the digest or one-way hash value of x using a one-way hash function h, i.e., y = h(x). It is easy to compute y from x, but almost impossible to compute x given y, even if the function h is known. Furthermore, even if x1 and x2 are similar, the corresponding digests y1=h(x1) and y2=h(x2) will be far apart. Information about MD5 digest can be found from RFC1321 or at http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html.)

Digest access authentication scheme is not intended to be a complete solution to the need of security for Internet. The scheme does not provide encryption of message (i.e. message confidentiality), message integrity, and non-repudiation. The digest scheme is meant to avoid the serious flaw in the basic scheme (i.e., sending password in clear text) and to replace the basic scheme.

Like basic scheme, digest scheme is based on a simple challenge-response exchange for user authentication. The server challenges the client with a nonce value, and expects a response, which is the digest of the username, password, the given nonce value, the HTTP method, and the requested URL. It is important to note that the password is not sent in cleartext, as in the basic scheme. A hash value involving the password is sent instead. Network snifters will not be able to reconstruct the password from the intercepted digest. The nonce, which ideally should be different for difference request, is used to prevent "replay attack".

The details of the authentication steps involved in the digest scheme are as follows:

  1. The client requests for a web resource protected by digest authentication scheme, via an HTTP GET request.
  2. The server returns a "401 Authentication Required" response, specifying the authentication scheme, the realm, and a nonce, in the "WWW-Authenticate" response header.
  3. The client combines the password, nonce, HTTP method and URI; computes the digest; and sends this digest back to the server. An example of computation is as shown:
    MD5(MD5(<password> + ":" + <nouce> + ":" + MD5(<method> + ";" + <uri>)
  4. The server independently generates the hash and verifies with the hash received. It sends back the resource requested (with status "200 OK") if the two hash values match. Otherwise, a "401 Authentication Required" will be sent, and the authentication process repeats (or until the client cancels the request).

Implementing Digest Access Authentication

Like basic scheme, the configuration needed for using digest access authentication in the Apache HTTP Server may involve the following 3 steps:

  1. Create a password file;
  2. Configure the Apache server to use this password file;
  3. Optionally, define a group file, and apply access control at group level.

Step 1: To create the password file, you can use the utility "htdigest" provided in "%APACHE_HOME%\bin" as follows:

> htdigest -h
Usage: htdigest [-c] password-file realm username
The -c flag creates a new file.
   
> htdigest -c ..\conf\digest.users "members only" bob
Adding password for bob in realm members only.
New password: ***
Re-type new password: ***
   
> htdigest ..\conf\digest.users "members only" alice
Adding user alice in realm members only
New password: *****
Re-type new password: *****

The content of the digest user file "conf\digest.users" is as shown:

bob:members only:f64f2af9501033efe7c402417681e05b
alice:members only:d65afa1afb84c30a7547aecff4431700

Notice that, unlike basic scheme, each pair of username/password is associated with a realm. The username and password is only valid for that particular realm.

Step 2: To activate the digest scheme, you have to include these directives in the Apache's configuration "conf\httpd.conf" (or .htaccess if override is allowed):

# uncomment these two lines to load the digest authentication module
LoadModule digest_auth_module modules/mod_auth_digest.so
......
AddModule mod_auth_digest.c   # for older Apache versions only
......
   
<Directory protected-directories>
  AuthType Digest
  AuthName "members only"
  AuthDigestFile conf/digest.users  # Use AuthUserFile for Apache 2
  Require user bob
</Directory>

Directive "AuthType Digest" is used to activate the digest access authentication. Directive AuthDigestFile is used to specify the location of the password file. (If you encounter error with AuthDigestFile directive, use AuthUserFile directive instead, for Apache 2.) The realm in the AuthName must match the user file and it is case sensitive.

Step 3: Optionally, you can use a group file to control access at the group level. The format of the group file is the same as the basic authentication. For example:

admin: alice alan
audit: bob bill

An example of configuration is as follows:

<Directory protected-directories>
  AuthType Digest
  AuthName "members only"
  AuthDigestFile conf/digest
  AuthDigestGroupFile conf/digest.groups
  Require group admin
</Directory>

Directive AuthDigestGroupFile is used to specify the group file (instead of AuthGroupFile in the basic scheme).

Message Trace

A trace of messages involved in the digest access authentication is as follows. A directory called "digest_auth" is created under "htdocs", containing a file "test.html". Assuming that Apache HTTP server is running on port 8000.

Digesting Details

When a client requests for a protected resource under the digest scheme, the server returns a "401 Authentication Required" response, which includes a "WWW-authenticate" header. The following information is included in the "WWW-authenticate" header:

Upon receiving the "401" response from the server, the client must include an "Authentication" header and re-submit the request. The following information is provided in the "Authentication" header:

Security Considerations

Basic access authentication scheme has the following flaws:

Digest scheme overcomes these flaws. However, it does not assure message confidentiality and non-repudiation. It merely provides a more secure and safe way for clients to submit their credential. It is not as secure as Kerberos, client-side private key, or SSL, but much better than telnet, ftp and of course, basic authentication scheme.

You should certainly replace the basic scheme with the digest scheme, unless password security is no of your concern.

One final note: by modern cryptographic standards, the MD5 digest algorithm is considered weak. (Need to verify!)

Configuration Directives:

Refer to "%APACHE_HOME%\htdocs\manual\mod\mod_auth_digest.html" for details of the configuration directives.

AuthDigestFile: specifies the location of the password file for digest authentication, which can be created using the htdigest utility provided. (Use AuthUserFile if you encounter error.)

AuthDigestFile digest-user-filename

AuthDigestGroupFile: specifies the location of the group file. Each line of the group file contains a groupname followed by a colon, followed by the members' username separated by a space. The format of the group file is the same as the basic authentication.

AuthDigestGroupFile digest-group-filename

Using Database for Password files

Matching the username/password from a flat file created using utilities "htpasswd" and "htdigest" is slow if the number of users is large. You can use a database to store the username/password to speed up the password verification process.

Read the Apache documentation.

 

REFERENCES & RESOURCES

Latest version tested: Apache HTTP Server 2.2.14