Apache + mod_rewrite: Exclude certain paths from basic authentication
Sometimes it's necessary to protect a website or -application with basic authentication, but leave certain urls publicly available. There are many examples which either use the <Location> directive or do not use mod_rewrite. But you cannot build a modern web-application without mod_rewrite. In some cases it is necessary or could be useful to place the basic authentication settings in an .htaccess file instead of the server/vhost configuration, which means, that the <Location> directive could not be used.
Though the combination of basic authentication and mod_rewrite is kind of special, because the Apache applies the authentication rules twice. First for the primary request, where the variable REQUEST_URI contains the url requested from the client and thereafter for the internal subrequest after the rewrite rules has been applied. If you rewrite all urls that does not match a file, a link or a directory to index.php, the subrequest will have /index.php as REQUEST_URI. In our case that lead to, that the granted access for the directory worked for the primary request, but not for the internal subrequest. We solved this as follows:
# Active rewrite engine
RewriteEngine On
# Set environment variable using rewrite for the desired url
# Attention: The url does not start with a "/" here
# Do not add the [L] flag to allow further processing of rewrite rules
RewriteRule ^the-url/you-want/to-match/.*$ - [E=MATCH_DOWNLOAD_URL:1]
# The normal rewrites for our application
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]
# Activate basic authentication
AuthType Basic
AuthName "Please login"
AuthUserFile /absolute/path/to/.htpasswd
# Grant access to the desired url (matches in the primary request)
Require expr %{REQUEST_URI} =~ m#^/the-url/you-want/to-match/.*$#
# Grant access, if the environment variable is set (matches in the subrequest)
Require env REDIRECT_MATCH_DOWNLOAD_URL
# Otherwise ask for username and password
Require valid-user
The Require directives behave as they were grouped by <RequireAny> meaning one condition must be satisfied to make the request authenticated.
This website uses Disqus for displaying comments. Due to privacy regulations you need to explicitly consent to loading comments from Disqus.
Show comments