ITS and UVa logos for printed output

ITS Web Resources

Restricting Website Access with .htaccess Files

Table of Contents

Why limit access to a Web site?

If all the pages at a Web site pertain to a select group of people - for example, a society with restricted membership - the provider might limit access to members so that the information is kept private.  Another person might have two or more categories of information with different audiences.  Someone else might have general information and additional subsets of information, intended for specific groups (only).  The general information would be open to all visitors, but only specific persons would be allowed to view the subset(s) meant for the groups alone.

Limiting access with a password

The "password" must be recognizable as a string of characters. Generally the password has an associated "login".  For example, I might want to know if you are a member of one of my clubs and know the password for it, or I might want to know who you are as well as have your password, or I might allow anyone from a machine whose address ends in "" to enter, in which case the person's IP address could act as the "login".

What to do to limit access

There are at least two steps required to "lock" files from access by the general visitor to your Web site.  The first step is to set up a login/password pair that will act as a key to the restricted set of files.  The second step is to create a file called ".htaccess" - that is "dot-htaccess" - and position it properly so that it can police your visitors.

How to create the login/password pair

Here, you must know enough about the UNIX operating system that you can give UNIX commands and move around the file system.  The examples here are about as simply structured as possible, but nonetheless this step cannot (yet) be carried out in any way other than by logging onto the computer that holds your Web pages.  The command to create the login/password pair is htpasswd and has two different forms:  one for creating the file that will hold the encrypted entries, and the other for adding additional pairs once the file exists.  To create an authorization  file  named ".htpasswd" with a login for "friend", you type something similar to this:

htpasswd -c .htpasswd friend <Return or Enter>

The computer will ask you for a password that will then be paired with the login "friend". To create another pair, let's say for those on your swim team, whether immediately or at some later date, use a command similar to this:

htpasswd .htpasswd swimmer <Return or Enter>

You will be similarly asked for a password that will be paired with the login "swimmer".

The login/password combinations are encrypted so they will not be useful to someone who might get a look at the file. It is up to you to remember the passwords - the file is of no help. In this example, the login/password pairs were friend/mybuddy and swimmer/frog. Use the command more .htpasswd to see the contents of the file. You should see the logins, friend and swimmer, each followed by a colon (:) and some nonsense string of characters similar to this:

        /home/user_id $ more .htpasswd


Where to put the authorization file

It is best not to have the file in the public_html directory with your Web pages - that directory is wide open from a security standpoint. At least put the authorization file at the same level in your UNIX account's tree as the public_html file. For most users, this will be at the login directory level with a location similar to "/home/user_id", where user_id is the owner's user_id, as in the above example.

Where to put the .htaccess file

In the simplest case - when your entire Web site is to be password-protected, put the .htaccess file in the public_html directory. A listing of the home directory would probably show these files and directories along with many others:

        /home/user_id $ ls
             .........    .........    ..........
        .htpasswd            public_html
        /home/user_id $ cd public_html 
        /home/user_id/public_html $ Ls -a
           4 drwxr-xr-x   2 user_id    usr    4096 Oct 11 1998  ./ 
           8 drwxr-xr-x   3 user_id    usr    8192 Jun 28 12:02 ../
           4 -rw-r--r--   1 user_id    usr     135 Jun 28 12:01 .htaccess 
           4 -rwxr-xr-x   1 user_id    usr    2438 Jun 10 1998  home.html* 
           4 -rwxr-xr-x   1 user_id    usr     483 Jun 10 1998  test.cgi*

A second, differently constructed example that has protected subdirectories for our friends and swimmers might look something like this:

        /home/user_id/public_html $ Ls -a
           4 drwxr-xr-x   2 user_id    usr    4096 Jun  7 13:12 ./
           8 drwxr-xr-x   3 user_id    usr    8192 Jun 28 12:02 ../ 
           4 -rwxr--r--   1 user_id    usr    2438 Jun 10 1998  home.html 
           4 drwxr-xr-x   2 user_id    usr    4096 Jun 7  13:12 pals/ 
           4 drwxr-xr-x   2 user_id    usr    4096 May 14 16:35 swimteam/ 
           4 -rwxr-xr-x   1 user_id    usr     483 Jun 10 1998  test.cgi*

Note that there is no .htaccess file at the public_html level. Any visitor can use or view the files "home.html" and "test.cgi". The .htaccess files are now going to be in their respective subdirectories whose listings might appear thus:

        /home/user_id/public_html $ cd pals 
        /home/user_id/public_html/pals $ Ls -a 
           4 drwxr-xr-x   2 user_id    usr    4096 Jun  7 13:12 ./ 
           8 drwxr-xr-x   3 user_id    usr    8192 Jun 28 12:02 ../ 
           4 -rwxr--r--   1 user_id    usr     135 Oct 11 1999  .htaccess 
           4 -rwxr--r--   1 user_id    usr    2438 Jun 10 1998  home.html 
           4 -rwxr--r--   1 user_id    usr    2438 Oct 11 1999  club.html 
           4 -rwxr-xr-x   1 user_id    usr     483 Jun 7 13:12  test.cgi*

        /home/user_id/public_html/pals $ cd ../swimteam 
        /home/user_id/public_html/swimteam $ Ls -a 
           4 drwxr-xr-x   2 user_id    usr    4096 May 14 16:35 ./ 
           8 drwxr-xr-x   3 user_id    usr    8192 Jun 28 12:02 ../ 
           4 -rwxr--r--   1 user_id    usr     135 Jan 28 10:12 .htaccess 
           4 -rwxr--r--   1 user_id    usr    2438 Jan 20 09:48 home.html 
           4 -rwxr--r--   1 user_id    usr    2438 May 14 16:35 schedule.html 
           4 -rwxr-xr-x   1 user_id    usr     483 Mar  5 08:03 test.cgi*

What text is in the .htaccess file?

There are several "authorization types" that must be named so that http protocol connections know where to and how to protect your files.

Example 1

Allow ONLY users whose connections come from the "" domain. The file /home/user_id/public_html/.htaccess contains the following attributes:

        AuthUserFile /home/user_id/.htpasswd
        AuthGroupFile /dev/null
        AuthName AllowFromUVa
        AuthType Basic

        order deny,allow
        deny from all
        allow from

Note that the first action is to deny everyone, but continue to check and, if the address contains "", to allow access.

Example 2

Allow ONLY users who know the "friend/mybuddy" pair to access the files in /home/user_id/public_html/pals. The .htaccess file—in the public_html/pals directory—needs these attributes:

        AuthUserFile /home/user_id/.htpasswd 
        AuthGroupFile /dev/null 
        AuthName ExampleAllowFriends 
        AuthType Basic 

        require user friend

Note that there is nothing magic about AuthName. This is just an "identifier" that helps the reader to know what the purpose of the .htaccess file is.

Example 3

Allow ONLY visitors who are on the swimteam, to whom you have given the login/password pair "swimmer/frog". This .htaccess file goes in the directory named /home/user_id/public_html/swimteam:

        AuthUserFile /home/user_id/.htpasswd 
        AuthGroupFile /dev/null 
        AuthName ExampleAllowSwimmers 
        AuthType Basic

        require user swimmer

These examples rely on the information in the authorization file named ".htpasswd". When a person clicks on a URL in the swimteam subdirectory, a window pops up with two text fields - one in which to type the login, the other in which to type the password.

What are the basic directives?

There are several entries allowed in the .htaccess file. For a more thorough explanation of them, please refer to the Apache Web site's documentation at The functions of the more frequently used ones are summarized in the following table, along with examples.

Directive Scope of Action Example
Allow(all, [from domain list]) a list of domains to allow access to a directory allow from
Deny(all, [from domain list]) a list of domains to deny access to a directory deny from
Order(allow,deny or deny,allow) Specifies which has precedence. Always specify if followed by Deny from or Allow from see examples above
Require(user [list], group [list] valid-user) User must login with specified name/group or be authorized by the Auth* commands require user mark david anna sean
AddType(mime/type [extension list]) Tells server what the mime/type to send for a given extension AddType image/gif GIF GFF FIG
AuthUserFile(filename) Specifies the FULL path to the file to use as a password list AuthUserFile /home/mst3k/.secret
AuthGroupFile(filename) Specifies full path to file to be used to organize users into groups (rarely used) AuthUserFile /home/mst3k/.secretgrp
AuthName([text]) The prompt string shown to users when given the dialogue box Zork's Secret Directory
DefaultType(mime/type) Tells server what mime/type to use for a file having an unknown (or no) extension DefaultType text/html
ErrorDocument(3-digit-code [filename or text or url]) Customize error responses rather than use boring generalized error documents provided ErrorDocument 401 /~userid/error401.html
ForceType(mime/type) Forces the mime type to tell the browser it is sending a particular type of file no matter what the extension actually is ForceType image/gif
Satisfy(any, all) If there are both Allow and Require directives, this tells server to check if one or all directives must be true Satisfy all
<Files> </Files> Used to apply directives to only a select group of files, e.g could password protect *.gif files only (separate lines in file) <Files *.gif>
Deny from

Page Updated: 2013-02-28