Skip to main content

zonena.me

Apache mod_rewrite Based on Logged in User

I’ve been working on a project recently where I want to redirect users logging into Apache to that user’s personal directory. There is a lot of incorrect information out there.

Most sites recommend something close to the following: (NOTE: This is wrong)

RewriteEngine On
RewriteCond %{REMOTE_USER} uid=([^,]+),
RewriteRule ^/users/$ /users/%1

There’s a few problems with this.

  1. The RewriteCond match pattern is completely wrong. %{REMOTE_USER} won’t contain uid= and should not be part of the match.
  2. In the RewriteRule %1 has no meaning so if this matched it would redirect get sent into an infinite loop, since /users/ redirects to /users/.
  3. Because of the way mod_rewrite works %{REMOTE_USER} isn’t necessarily populated and may be empty. If this is the case, the entire block will be skipped.

As I’ve said before (mostly to remind myself) reading the documentation is essential.

For instance, to rewrite according to the REMOTE_USER variable from within the per-server context (httpd.conf file) you must use %{LA-U:REMOTE_USER} - this variable is set by the authorization phases, which come after the URL translation phase (during which mod_rewrite operates).

On the other hand, because mod_rewrite implements its per-directory context (.htaccess file) via the Fixup phase of the API and because the authorization phases come before this phase, you just can use %{REMOTE_USER} in that context.

There are basically two options here. If you’re adding the RewriteRule into your main Apache config file (httpd.conf), mod_rewrite runs before authentication. In this cause you need to use a look ahead assertion.

If you’re using a .htaccess file in a directory then mod_rewrite runs after authentication.

So if you’re adding the rule to your Apache server config (httpd.conf) the final rule looks like this:

RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} ^[a-z].*
RewriteRule ^\/(.*)$ /%{LA-U:REMOTE_USER}/$1

And for .htaccess:

RewriteEngine On
RewriteCond %{REMOTE_USER} ^[a-z].*
RewriteRule ^\/(.*)$ /%{REMOTE_USER}/$1