Apache is the dominant server for PHP content although IIS can be a respectable substitute. However, upon first inspection IIS does not appear to be as flexible as Apache, particularly regarding dynamic configuration through .htaccess. There are generally three main areas where .htaccess files are used:
- URL rewriting
- Providing basic or digest authentication
- Denying access to a directory
The CodeIgniter framework for example contains an .htaccess file in the root of the application and system folders to deny direct access to important site resources. Additionally, we may wish to have an uploads folder where file access is managed through our PHP application; we cannot use ACLs in such an example as the anonymous IIS user must have access to the resource yet the client should not be able to access it directly.
Apache lets us define this behavior easily by adding one line to an .htaccess file in the protected directory:
deny from all
The client will now receive a 403 Forbidden error should they try to to access the directory or any resource within. ASP.NET developers may use forms or windows authentication to address the problem but these are not easily available from a PHP application. Luckily IIS 7 includes a Request Filtering module which allows us to deny access to a directory using a web.config file:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <security> <requestFiltering> <denyUrlSequences> <add sequence="/" /> </denyUrlSequences> </requestFiltering> </security> </system.webServer> </configuration>
This configuration will send the client a 404.5 Not Found status. While the status code is not as accurate as Apache’s 403 status, it does at least prevent access to the directory and it’s resources.
It’s also possible to register an HttpForbiddenHandler instead of using request Filtering for ASP.NET enabled servers. This configuration is required for versions of IIS prior to 7 and has the advantage of sending the correct 403 status code to the client.
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <add name="Deny" path="*" verb="*" type="System.Web.HttpForbiddenHandler" /> </handlers> </system.webServer> </configuration>