2

I have spent a tremendous amount of time the last week trying to figure this out, but no matter what I try I cannot get this to work. My web host said they did not have anyone who knew enough about .htaccess files to get this working (encouraging, right?), and the company I purchased my CMS from also could not determine a solution. I've also read dozens upon dozens of answers on here and on other websites, but I simply cannot fix my problem.

Here's the deal: My CMS - Invision Power Board - generates the following .htaccess file which goes in the root of the website:

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

I have a subdirectory, sub_dir, that I need to password protect using a .htaccess file in the subdirectory. I setup the password protection through cPanel and if the .htaccess file in the root of the website is disabled it works fine. If the .htaccess file in the root of the website is not disabled, however, then when I browse to sub_dir the homepage is displayed. At first I thought the homepage being displayed might have something to do with the 404 page rewrite, but the homepage is still displayed even if I remove the rewrite conditions and rule for the 404 page.

The code in the .htaccess file in sub_dir is:

AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user

As I previously mention, the password protection works when the .htaccess file in the root directory is disabled. It also works when I remove the bottom rewrite conditions and rule (the lines for index.php), but removing the rewrite conditions and rules for the 404 page does not affect anything.

I have tried dozens of potential solutions, none of which have worked. To name a few, I tried Poncha's answer below:

RewriteCond %{REQUEST_URI} !^sub_dir

I've also tried this:

RewriteRule ^/sub_dir  - [L]

As well as many, many other things that I don't really even remember now. The point is, nothing has worked so far. I also did try all possible combination with regard to the leading and following slashes.

My server is running Apache 2.2.22.

I am seriously at my wits end here. Please help.

4
  • possible duplicate of How to stop subdirectory from inheriting root .htaccess rewrite?
    – Jon Lin
    Jul 15, 2012 at 22:23
  • @JonLin - Oops, my bad. I thought I had deleted that question. I asked that this morning and, in addition to no one responding, the question became convoluted as I made updates to it as I tried different things. This question is clear and concise. I deleted my old question. Thanks.
    – Nate
    Jul 15, 2012 at 23:39
  • 1
    It isn't clear to me what exactly the behavior you're expecting is. Is there an index.html or index.php in the target folder you want it to load, or are you expecting a password protected directory listing? If you try to directly access an actual file in the subfolder, does it work as expected? (It should).
    – mootinator
    Jul 18, 2012 at 4:55
  • 1
    Hmmm.. I guess what I'm not seeing is what urls you accessed to verify the settings. Knowing those might make it easier to diagnose, as you might not be testing for a condition that would shed some light on this. Also, you posted the .htaccess for the root of the website... but what is in the httpd.conf file?
    – whiskeyfur
    Jul 23, 2012 at 16:37

8 Answers 8

2

It would seem like you've already tried this, it's the most obvious answer (as poncha pointed out) and it's probably the most likely to show up in a mod_rewrite tutorial/guide. By exlcuding the directory using a RewriteCond, noting that the match of the condition is against the %{REQUEST_URI}, which begins with a /":

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

EDIT:

Looking at what you've tried, this also is wrong. You don't want the leading slash in the match of the RewriteRule when it is in an htaccess file:

<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On

RewriteRule ^sub_dir  - [L]


RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
4
  • Jon - Thank you for your answer, but I'm afraid it did not work :(.
    – Nate
    Jul 17, 2012 at 22:37
  • 1
    @Nate Without any detailed explanation of how it isn't working, we're not going to be able to help you any further.
    – Jon Lin
    Jul 17, 2012 at 22:38
  • I'm afraid that did not work either. If I gave you ftp access, could you give it a try?
    – Nate
    Jul 17, 2012 at 23:01
  • @Nate are you sure there is nothing else in your htaccess file? I put either of these in a blank htaccess file in the document root of a vanilla apache install and both work fine, letting all requests starting with /subdir/ pass through unaffected.
    – Jon Lin
    Jul 17, 2012 at 23:13
1

This rule forwards to the homepage if the requested path is not an existing file, and is not an existing directory.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Clearly, because you are being forwarded to the homepage, the server believes that either the sub_dir directory does not exist, or the request for sub_dir is being redirected to something which does not exist.

The first thing to check in this scenario is, of course, whether sub_dir is an actual directory, keeping in mind that depending on your the directory name will be case sensitive in most cases where Apache is being run, and also keeping in mind that a symlink is not necessarily treated the same as a directory.

1
1

How about you try just doing this in your sub_dir .htaccess to disallow modrewrite to propagate into your sub_dir :

    ## turn off rewrite engine
    RewriteEngine Off
    ## now do your auth stuff
    AuthUserFile "/home/[user]/public_html/.htpasswd"
    AuthType Basic
    AuthName "subdir"
    require valid-user

and if you really need rewrite rules to work inside sub_dir then do them specifically in that .htaccess file so there is never any confusion. As soon as you execute RewriteEngine On/Off then the rules from the parent folder do not apply directly. They are read from that folder first then the root.

1

First notice:

AuthUserFile "/home/[user]/public_html/.htpasswd"

It looks like your .htpasswd file is in a publicly accessible place (public_html). This is a security problem, you shoul dput that file somewhere where the apache user can read it (check directory anf files rights) but certainly not on a place under a DocumentRoot. No one shoul dbe able to requets directly for a .htpasswd file, it's a server-side only file. But that's not related to your problem.

Your main problem is that you did not answer @Jon Lin & @mootinator questions. What files are you trying to request in sub_dir, is there some html files there, another index.php file? Should you allow directory listing in this directory? How do you make your tests.

When a request on sub_dir is made the parent .htaccess is applied by default (trying to redirect every request you can imagine to a boostrapper index.php, except for missing images files and except for existing directories or files). So by requesting a real file in sub_dir you should'nt have any problem with theses rules. A good way to test that is to comment Rules on your root .htaccess.

You said you made some tests without the root .htaccess file and it worked. So it's maybe the removal of Options -MultiViews which made your tests ok. MultiViews is part of content-negociation and is a very magical word with some very strange behaviors, so let's say for example you are requesting subd_dir/foo in your tests MultiViews could find a file sub_dir/FoO.html and serve it. Remove MultiViews and your tests will not work anymore (maybe). @Mootinator proposals on symbolic links problems could also be valid, and you could also have something in the tested files redirecting to an url catched by the first rule, there is no end to strange things. But for sure "it does not work" is not enough, what is "it"?

As I said you need to give us more information. And give all other readers (even in the future) enough element to see if your problem could be related to their problems. The goal is not to hire some experts to work directly on your server but to get valid answers to valid and detailled problems.

1

The solutions above don't work because they don't address the fundamental problem which is that the sub-folder to be excluded from the rules is password protected.

When the initial access is rejected by Apache and the login dialog box is presented, the rewrite rules kick in but can't redirect the client to an accessible file, so the 404 error occurs. To solve this problem we need to provide a "dummy" file to which the client can be directed when the initial access attempt fails.

ErrorDocument 401 /failed_auth.html
RewriteCond %{REQUEST_URI} ^/pwd-protected-sub-folder/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]
0

Add another RewriteCond to exclude your desired sub_dir (to both rules):

RewriteCond %{REQUEST_URI} !^sub_dir
1
  • Thanks for your help. I tried that, and I'm afraid it did not work. Any other ideas?
    – Nate
    Jul 16, 2012 at 21:17
0

Adding this in the hope that it helps someone else. @Mike L was on the right track with this I think. I had a similar situation (htaccess password protected sub-directory with rewrite rules in the root htaccess which I still needed for the main site). The solution for me in the end was to simply add this to the root .htaccess file.

ErrorDocument 401 "Unauthorised"

You'll still need to add the relevant rules to allow access to the sub-directory of course, but the password request not displaying was fixed using the above. Hope it helps!

0

For a site using plain vanilla cPanel-based shared hosting (Apache 2.2), I solved what appears to be the same problem by adding a file named "401.shtml" to the document root (public_html). The mere existence of the file, without even an ErrorDocument 401 directive in the .htaccess, solved the problem.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .