使用前端控制器脚本时,不能从基本身份validation中排除path

我有一个小的PHP / Apache2的Web应用程序,我想做两个看似不兼容的操作:

  1. 通过一个PHP脚本(一个“前端控制器”,如果你愿意的话)
  2. 使用HTTP基本authentication来保护除API调用以外的所有内容

我可以单独满足这两个要求中的任何一个,当我试图同时做到这一点时,我被封锁了。 没有很好的理由,我试图完全用Apacheconfiguration完成这些要求。

这里是作为例子陈述的要求。 这个URL的GET请求:

 http://basic/api/listcars?max=10 

应该通过front.php发送,而不需要基本的身份validation。 front.php会得到/api/listcars?max=10并做任何需要的。

这是我认为应该工作。 在我的/etc/hosts添加了

 127.0.0.1 basic 

我正在使用这个Apacheconfiguration:

 <Location /> AuthType Basic AuthName "Home Secure" AuthUserFile /etc/apache2/passwords require valid-user </Location> <VirtualHost *:80> ServerName basic DocumentRoot /var/www/basic <Directory /var/www/basic> <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^(.*)$ /front.php/$1 [QSA,L] </IfModule> </Directory> <Location /api> Order deny,allow Allow from all Satisfy any </Location> </VirtualHost> # another extant vhost in the same Apache2 config/server, for completeness <VirtualHost *:80> ServerName dustbin ServerAlias *.dustbin DocumentRoot /var/www/dustbin </VirtualHost> 

但是我仍然总是得到一个HTTP 401: Authorization Required响应。 我可以通过改变<Location /api>进入工作状态

 <Location ~ /api> 

但是这允许超过我想要通过基本的身份validation。

我也尝试将<Directory /var/www/basic>部分更改为<Location /> ,但是这也不起作用(并且导致传递给脚本的PATH_TRANSLATED有一些奇怪的值)。

我四处search,发现了许多select性排除基本身份validation的例子,但没有一个也包含了前端控制器。

我当然可以做一些事情,像在前端控制器中处理基本身份validation,但如果我可以让Apache做到这一点,而不是我的PHP代码,所有的身份validation逻辑。

一位朋友build议把它分解成两个虚拟主机,我知道这也是可行的。 实际上,这曾经是两个独立的虚拟主机。

<Location />位于虚拟主机之外,因为我希望所有虚拟主机默认都需要基本的auth。 我希望做的一个例外是在这个特定的虚拟主机上以/ api开头的所有URI。 我省略了其他的鬼,因为它们似乎与我的问题没有关系。

我在Ubuntu 12.04上使用Apache 2.2.22 / PHP 5.3.10。

由于修改path的RewriteRule位于<Directory>块(这是为了使%{SCRIPT_FILENAME}具有完整的文件path而完成的),所以[PT]标志隐含在规则中。 由于应用了[PT]标志,所以新请求的URL将根据位置重新映射 – 而<Location /api>部分不再适用于请求。

因此,有几个select。

  • 把你的重写规则放在<Directory>块之外。

     <VirtualHost *:80> ServerName basic DocumentRoot /var/www/basic RewriteEngine On RewriteCond /var/www/basic%{REQUEST_URI} !-f RewriteCond /var/www/basic%{REQUEST_URI} !-d RewriteRule ^(.*)$ /front.php/$1 [QSA,L] <Location /api> Order deny,allow Allow from all Satisfy any </Location> </VirtualHost> 
  • 使用该正则expression式<Location> – 可以限制它以防止意外的匹配。

     <Location ~ "(^|^/front\.php)/api/[^/]*$"> 
  • 使用FallbackResource而不是mod_rewrite

     FallbackResource /front.php