Forum Moderators: phranque
The gist of the issue is that I have a standard rewrite, which, given a URI of
/template/templateName/uniqueContentIdentifier
is rewritten as
/template/templateName.php?contentName=uniqueContentIdentifier
Rather than duplicate all the templates and rewrites for administrative previewing, I made the rewrite rules match against /admin/template/etc as well, while appending a dummy variable to the rewritten query string. This dummy variable's presence is then used within the template script to trigger the "preview" mode.
RewriteCond %{REQUEST_URI} ^(/admin)?/template/.* [NC]
RewriteRule ^(/admin)?/template/(.*)/(.*) /template/$2.php?contentName=$3&$1 [L,NC]
All that is fine and dandy and functional, except, naturally, I need to keep non-authenticated users from triggering the "preview" mode by hitting the poorly obfuscated URLs of /admin/template/etc. Since the "admin" directory has an .htaccess authentication requirement, I thought I could test against the REMOTE_USER and whether the REQUEST_URI was going to trigger one of the rewrite rules while containing the admin path... If the test was positive, then throw a forbidden return to the un-authenticated snoop.
RewriteCond %{REQUEST_URI} .*/admin/template/.* [NC]
RewriteCond %{LA-U:REMOTE_USER}!=admin
RewriteRule .* - [F]
Unfortunately, the above prevents even an authenticated "admin" from proceeding into the template rewrite rules. I've also attempted the above rewrites within the site's root .htaccess file so as to not require the look-ahead of REMOTE_USER, but without any effect. Everything I read online (both in the apache docs, and then in posts for this and other forums on external sites) seems to indicate what I'm attempting should be feasible, but why it fails is now beyond me. I suppose I could just add into each of the templates a test for a valid REMOTE_USER setting, but I'd rather something a touch more elegant along the lines I've been trying.
Any thoughts as to where I am going astray?
The rewrite log from one request using the above rules follows:
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83b438/initial] (2) init rewrite engine with requested uri /admin/template/foo/bar
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83b438/initial] (3) applying pattern '.*' to uri '/admin/template/foo/bar'
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83b438/initial] (3) applying pattern '.*' to uri '/admin/template/foo/bar'
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83d638/subreq] (2) init rewrite engine with requested uri /admin/template/foo/bar
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83d638/subreq] (3) applying pattern '.*' to uri '/admin/template/foo/bar'
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83d638/subreq] (3) applying pattern '.*' to uri '/admin/template/foo/bar'
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83d638/subreq] (2) forcing '/admin/template/foo/bar' to be forbidden
192.168.1.104 - - [19/Jan/2005:21:23:15 -0500] [sloth/sid#829888][rid#83b438/initial] (2) forcing '/admin/template/foo/bar' to be forbidden
Welcome to WebmasterWorld!
This appears to be a variation on the "prevent direct access to URL normally reached only by rewrite" theme. In that case, you need to get the originally-requested URL by using %{THE REQUEST} instead of %{REQUEST_URI}. While %{REQUEST_URI} may be changed by rewriting, %{THE_REQUEST} is not.
The format of %{THE_REQUEST} is pretty much what you see in a raw log file:
GET /template/templateName/uniqueContentIdentifier HTTP/1.1
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /direct-access-forbidden-filename-here\ HTTP
RewriteRule . - [F]
Jim
Since the processing is actually just rewriting once upon the request for any given situation, REQUEST_URI should not be changing per line. Each condition block, if met, stopped following lines processing, and none of the rewrites were redirecting to something which would trigger secondary rules.
After trying a few variants, I actually managed to get things working as originally written, albeit with a slight change to the response concept. Rather than killing off the non-authenticated "/admin/template/.*" request with a Forbidden response:
RewriteRule .* - [F]
A simple redirect to a 404 or similar page with the [L] modifier does the trick, thereby allowing only authenticated users past that rule if the request includes an "/admin" string:
RewriteRule .* /autherror.php [L]
Odd that the [F] rule in this situation causes such a failure, though.
Also likely to be a tad frustrating for the designer and sitebuilder since they now have to throw together another unplanned one-off page. Still, they'll be happy not having to upload and reconciling templates in two separate directories.