views:

34

answers:

2

Hello, I am creating a PHP application and I'm having a bit of trouble finding a solution for a problem I'm having. I need to somehow completely deny access to anyone trying to access files on a web server (likely by returning a 403 Forbidden error or something) via HTTP unless a certain condition is true, such condition would be checked on a per-connection basis. I need to find the best way to do this, I'm guessing I need to set some special settings in Apache that I can modify with PHP, but these Apache settings much obviously be configurable via PHP. As you can guess, I can write PHP well but have little experience with advanced Apache configurations.

I was thinking on that maybe if I used chmod via PHP to change the file's permissions for a validated user and have them change back when the connection is closed it would work, but if there are concurrent connections then the users connecting afterwords would have full access regardless of whether or not they are valid, the could actually just bypass the validation. Maybe there is a better way to do it like this however.

Thanks very much for the help!

A: 

It really depends on the "conditions" that you're checking, however you won't need to mess with chmod. If the "conditions" are all related to the HTTP request itself (ie- send the file based on the file requested, the query string, the IP address accessing, etc.) then you can do this strictly with .htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
Rewrite Base /

RewriteCondition {...}
RewriteRule (.*) - [F]
</IfModule>

This will redirect them to a "Forbidden" header if they match the conditions specified in {...}. See This resource for some examples.

If you need more control or if you want to deny files based on something more specific (for instance- send a 403 error if they are not logged in) then you'll want to redirect to a PHP script.

.htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
Rewrite Base /

RewriteRule (.*) parse.php
</IfModule>

parse.php:
if({conditions}){
    header("HTTP/1.0 403 Forbidden"); // 403 error!
} else {
    /* include() the file if it's PHP, otherwise just echo the file contents */
}
steven_desu
+1  A: 

put your files into a directory and deactivate http access via .htaccess. then write a php script that checks that condition and if it is true then return the requested file via php like this:

<?php
define(DIR, "save_folder/"); 
$filename='the_file_to_show.pdf'; 
$fileextension= explode(".", $filename);
header("Content-type: application/$fileextension[1]"); 
header("Content-Disposition: attachment; filename=".$filename.""); 
header("Content-Length: ".filesize(DIR.$filename)); 
readfile(DIR.$filename);
?>

put this into your .htaccess

<Directory ~ "save_folder">
    Order allow,deny
    Deny from all
</Directory>
ITroubs
Funny how similar this looks to me code :D I was wondering if you could help me more with the .htaccess code however. I tried `RewriteEngine on RewriteRule ^(.*)$ - [F]` however I can still download the files if I access them directly (with google chrome at least). What should I be doing?
Ben
just edited my answer with the according code for your .htaccess
ITroubs
@Ben if you would tell us what kind of condition you are talking about, somebody might even come up with a .htaccess only solution for this.
Pekka
Great, seems to be working. Thanks very much ITroubs!
Ben