从root .htaccess重写规则中排除一个目录以允许它被密码保护?

上个星期我花了很多时间来解决这个问题,但不pipe我尝试了什么,我都无法把它工作。 我的网站主持人说,他们没有任何人对htaccess文件有足够的了解,以使其运行起来(鼓励,对吧?),而我从CMS购买CMS的公司也无法确定解决scheme。 我也在这里和其他网站上看过几十个答案,但是我根本无法解决我的问题。

这里的交易:我的CMS – Invision电源板 – 生成以下.htaccess文件,它位于网站的根目录:

<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> 

我有一个子目录sub_dir ,我需要在子目录中使用.htaccess文件进行密码保护。 我通过cPanel设置了密码保护,如果网站根目录下的.htaccess文件被禁用,它可以正常工作。 如果网站根目录下的.htaccess文件没有被禁用,那么当我浏览到sub_dir ,主页被显示。 起初,我认为显示的主页可能与404页面重写有关,但即使我删除了404页面的重写条件和规则,主页仍然显示。

sub_dir .htaccess文件中的sub_dir是:

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

正如我之前提到的,密码保护在根目录中的.htaccess文件被禁用时起作用。 它也适用于当我删除底部重写条件和规则(index.php的行),但删除404页的重写条件和规则不影响任何东西。

我已经尝试了几十种潜在的解决scheme,其中没有一个能够解决问题。 举几个例子,我尝试了Poncha的答案:

 RewriteCond %{REQUEST_URI} !^sub_dir 

我也试过这个:

 RewriteRule ^/sub_dir - [L] 

以及许多其他我现在还不记得的东西。 关键是,到目前为止没有任何工作。 我也尝试了所有可能的组合,关于前面的和后面的斜线。

我的服务器正在运行Apache 2.2.22。

我很认真地在这里结束。 请帮忙。

看起来你已经尝试过了,这是最明显的答案(正如poncha指出的那样),这可能是最有可能出现在mod_rewrite教程/指南中的。 通过使用RewriteCondparsing目录,注意条件的匹配是以%{REQUEST_URI}开始的,该开始于/ “:

 <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> 

编辑:

看看你已经尝试过,这也是错误的。 当它在htaccess文件中时,你不需要RewriteRule匹配中的前导斜杠:

 <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> 

如果请求的path不是现有的文件,并且不是现有的目录,则该规则转发到主页。

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

显然,因为你被转发到主页,服务器认为sub_dir目录不存在,或者sub_dir的请求被redirect到不存在的东西。

在这种情况下,首先要检查的是,是否sub_dir是一个实际的目录,请记住,在大多数情况下,根据您的目录名称区分大小写 ,同时也要记住,符号链接不一定被视为一个目录。

你怎么样只是在你的sub_dir .htaccess中这样做,不允许modrewrite传播到你的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 

如果你确实需要在sub_dir中使用重写规则,那么在.htaccess文件中专门执行它们,这样就不会有任何混淆。 只要您执行RewriteEngine On / Off,则父文件夹中的规则不会直接应用。 他们是从该文件夹中读取,然后是根。

首先通知:

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

它看起来像.htpasswd文件是在一个公共的地方(public_html)。 这是一个安全问题,你可以把这个文件放到apache用户可以读取的地方(检查目录anf文件的权限),但是肯定不在DocumentRoot的某个地方。 没有人能够直接请求一个.htpasswd文件,它只是一个服务器端文件。 但是这与你的问题没有关系

你的主要问题是你没有回答@Jon Lin&@mootinator的问题。 你想在sub_dir中请求什么文件,那里有一些html文件,另一个index.php文件? 你应该允许在这个目录中列出目录吗? 你如何做你的testing。

当对sub_dir发出请求时,会默认应用父.htaccess(尝试将每个请求redirect到一个boostrapper index.php,除了丢失的图像文件以及现有的目录或文件除外)。 所以通过在sub_dir中请求一个真实的文件,你应该不会遇到这些规则的问题 。 testing的一个好方法就是在你的根.htaccess上注释规则。

你说你做了一些testing没有根.htaccess文件,它的工作。 所以这可能是删除了Options -MultiViews ,这使得你的testing正常。 MultiViews是content-negociation的一部分,是一个非常神奇的词,有一些非常奇怪的行为,所以我们假设你在你的testing中要求subd_dir/foo可以find一个文件sub_dir/FoO.html并提供它。 删除多视图,你的testing将不再工作(也许)。 @Mootinator关于符号链接的build议也可能是有效的,你也可以在被testing的文件中有东西redirect到第一条规则所捕获的url,不会有奇怪的事情结束。 但是肯定“不起作用”是不够的,什么是“它”?

正如我所说,你需要给我们更多的信息。 给所有其他读者(即使在将来)有足够的元素来看看你的问题是否可能与他们的问题有关。 目标不是聘请一些专家直接在您的服务器上工作,而是为有效和详细的问题得到有效的答案。

上述解决scheme不起作用,因为他们没有解决的基本问题,即从规则中排除的子文件夹是密码保护。

当初始访问被Apache拒绝并且login对话框出现时,重写规则启动,但不能将客户端redirect到一个可访问的文件,所以会发生404错误。 为了解决这个问题,我们需要提供一个“虚拟”文件,当最初的访问尝试失败时,客户端可以指向这个文件。

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

添加另一个RewriteCond来排除你想要的sub_dir (对两个规则):

 RewriteCond %{REQUEST_URI} !^sub_dir 

添加这个,希望它可以帮助别人。 我认为@Mike L是正确的。 我有一个类似的情况(htaccess密码保护的子目录与重写规则在根htaccess中,我仍然需要为主站点)。 我最后的解决scheme是简单地将其添加到根.htaccess文件。

 ErrorDocument 401 "Unauthorised" 

您仍然需要添加相关规则以允许访问子目录,但是不显示的密码请求是使用上述方法修复的。 希望能帮助到你!

对于使用普通的基于cPanel的共享主机(Apache 2.2)的网站,我通过向文档根目录(public_html)添加一个名为“401.shtml”的文件解决了同样的问题。 文件的存在,甚至没有在.htaccess中的ErrorDocument 401指令,解决了这个问题。