Hack 97 Controlling Web-Server Access by Username and Group


Controlling access by hostname or IP is great when you want to ensure that only a network or machine you recognize is accessing your site or to block that pesky web spider that rudely ignores your robots.txt file. It is, however, used less often than user-based authentication.

To start the process, we're first going to create the user database. This database will contain all the usernames and passwords that will be authenticated against; they're not keyed to any specific directory, so you could use one database for 300 users spread across two dozen directories. To create the database, get into your Terminal and gaze blurry-eyed at the following command:

% htpasswd -c /Library/WebServer/.htpasswd morbus

It's nice and innocent, right? htpasswd is the name of the utility that creates and modifies the user database. The -c flag says if this database doesn't exist, create it. /Library/WebServer/.htpasswd is the full path to our database file, and you'll want to take special notice that it's outside Apache's document root (which, in OS X, is defined as /Library/WebServer/Documents). Sticking the file outside the document root ensures that no one can view this database from the Web. Finally, morbus is the user that you want to add to the database. Here's sample output from this command:

% htpasswd -c /Library/WebServer/.htpasswd morbus
New password: ********
Re-type new password: ********
Adding password for user morbus

You'll want to make sure that when you add new users to an existing database file that you do not use the -c flag. Doing so will overwrite your existing file with a brand-new one. Adding a user is a simple matter (note the lack of the -c flag):

% htpasswd /Library/WebServer/.htpasswd imam
New password: *********
Re-type new password: *********
Adding password for user imam

If you look at /Library/WebServer/.htpasswd, you'll see the added users:

% cat /Library/WebServer/.htpasswd

Next, it's really just a matter of telling Apache which directory we want to secure. You can insert the following block of code into your httpd.conf file; it'll protect the entire web server:

<Directory /Library/WebServer/Documents>
  AuthName "Protected Directory"
  AuthType Basic
  AuthUserFile /Library/WebServer/.htpasswd
  require valid-user

AuthName will appear as the title or description in the password box that a visitor's browser will show, whereas AuthType is set to the standard basic authentication (a digest authentication exists but is outside the scope of this hack). AuthUserFile should be self-explanatory.

The require line affords some discussion. With it, you can tell Apache to allow any user in the AuthUserFile access (as we've done earlier), or you can tell Apache to allow only certain people. In the following example, only the users morbus and imam can authenticate to realms with the name Protected Directory. Any other users in the AuthUserFile will be denied:

require user morbus imam

Users can also be defined by groups; for example, you could place dan, sbp, and morbus into a group called Marketing, and steve, geomisk, and sal into a group called Design. From there, you could restrict access by group instead of username. For these configurations and more about digest authentication, refer to Apache's authentication documentation (http://httpd.apache.org/docs/howto/auth.html) .