I currently do this with a directory on my local computer. Basically, just create a .htaccess file in that directory that looks like:
Order Allow, Deny
Deny from All
Then, use a PHP script to authenticate users. Once autenticated, you can use [man]glob/man to list all files in a directory (I use '.' so that files such as '.htaccess' aren't listed; later, when retrieving the file, check to make sure the first character isn't a '.' or '/'). Loop through the array and output the filenames as links, e.g.
<a href="myscript.php?download=my%20file.zip">my file.zip</a>
Note that you'll want to use [man]rawurlencode/man to encode filenames when echo'ing the URL portion of the output.
Finally, if $GET['download'] is not empty, the user has been authenticated, and the first character, $GET['download'][0] isn't a '.' or '/', output the appropriate headers to initiate a file download and then output the file. This is how I do this part:
header ('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header ('Content-Type: application/octet-stream');
header ('Content-Length: ' . filesize($_POST['download']));
header ("Content-Disposition: attachment; filename=\"{$_POST['download']}\"");
$fp = fopen($_POST['download'],'rb');
while(!feof($fp))
echo fgets($fp, 51200);
fclose($fp);