Symfony 应用程序和 API 在同一个 Apache 虚拟主机上
Symfony app and API on same Apache virtual host
我在 Apache 2.4 上开发由 Symfony v3 提供支持的遗留 PHP 应用程序。此应用程序受 Kerberos 身份验证保护。我的 Apache VirtualHost 看起来像:
Listen 80
<VirtualHost *:80>
DocumentRoot "/var/www/app"
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
require valid-user
# Symfony URL rewriting
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
[...]
我向这个应用添加了一个 API,URL 看起来像 /api/users
。问题是,就像我的整个应用程序一样,这个 API 由 Kerberos 保护,但我不想这样做。所以我尝试以这种方式向我的虚拟主机添加 LocationMatch 标签:
DocumentRoot "/var/www/app"
<LocationMatch "^((?!/api).)*$">
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
require valid-user
</LocationMatch>
[...]
这本来可以工作,但有一个问题。似乎 URL 重写是在执行之前执行的,我的 URI 被转换为这种形式:
/api/users => /app.php/api/users
而且我没能在这个新 URI 上应用我的 LocationMatch。
我被屏蔽了。如何访问受 Kerberos 保护的遗留应用程序,并在没有身份验证的情况下发布我的 API?
终于解决了
第一个问题,在Directory指令中使用mod_rewrite重定向到前端控制器。目录指令在位置指令之前处理,因此我的 URL 在我的位置指令之前被重写。所以我的 API url 变成了 /app.php/api
,并且脚本名称后面的部分不能用 Location 指令过滤。正如 Symfony Book 中提到的,我用 Apache 命令 FallbackResource 替换了 url 重写,它做同样的事情(重新路由到我的 Symfony 前端控制器),但是可以过滤我的 /api
URL 带有 Location 指令...所以应该可以使用 <LocationMatch "^((?!/api).)*$">
.
但我面临的第二个问题是 LocationMatch(或 Location ~
似乎做同样的事情)在 "positive lookahead" 上工作,如 ^/api
但似乎有一个错误当我像 /(?!api)
一样使用 "negative lookahead" 时,Apache 2.4.10(可能是由于 Kerberos 模块)。即使 /api
URL...
也会处理 LocationMatch 指令内容
我终于尝试了另一种解决方案,它适用于我的情况并解决了问题:
DocumentRoot "/var/www/app"
<Directory /var/www/app>
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
SetEnvIf Request_URI ^/api noauth=1
<RequireAny>
Require env noauth
Require valid-user
</RequireAny>
FallbackResource /app.php
</Directory>
我在 Apache 2.4 上开发由 Symfony v3 提供支持的遗留 PHP 应用程序。此应用程序受 Kerberos 身份验证保护。我的 Apache VirtualHost 看起来像:
Listen 80
<VirtualHost *:80>
DocumentRoot "/var/www/app"
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
require valid-user
# Symfony URL rewriting
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
[...]
我向这个应用添加了一个 API,URL 看起来像 /api/users
。问题是,就像我的整个应用程序一样,这个 API 由 Kerberos 保护,但我不想这样做。所以我尝试以这种方式向我的虚拟主机添加 LocationMatch 标签:
DocumentRoot "/var/www/app"
<LocationMatch "^((?!/api).)*$">
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
require valid-user
</LocationMatch>
[...]
这本来可以工作,但有一个问题。似乎 URL 重写是在执行之前执行的,我的 URI 被转换为这种形式: /api/users => /app.php/api/users
而且我没能在这个新 URI 上应用我的 LocationMatch。
我被屏蔽了。如何访问受 Kerberos 保护的遗留应用程序,并在没有身份验证的情况下发布我的 API?
终于解决了
第一个问题,在Directory指令中使用mod_rewrite重定向到前端控制器。目录指令在位置指令之前处理,因此我的 URL 在我的位置指令之前被重写。所以我的 API url 变成了 /app.php/api
,并且脚本名称后面的部分不能用 Location 指令过滤。正如 Symfony Book 中提到的,我用 Apache 命令 FallbackResource 替换了 url 重写,它做同样的事情(重新路由到我的 Symfony 前端控制器),但是可以过滤我的 /api
URL 带有 Location 指令...所以应该可以使用 <LocationMatch "^((?!/api).)*$">
.
但我面临的第二个问题是 LocationMatch(或 Location ~
似乎做同样的事情)在 "positive lookahead" 上工作,如 ^/api
但似乎有一个错误当我像 /(?!api)
一样使用 "negative lookahead" 时,Apache 2.4.10(可能是由于 Kerberos 模块)。即使 /api
URL...
我终于尝试了另一种解决方案,它适用于我的情况并解决了问题:
DocumentRoot "/var/www/app"
<Directory /var/www/app>
AuthType Kerberos
AuthName "App Login"
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbAuthRealms MY_REALM
KrbLocalUserMapping On
Krb5KeyTab /usr/local/apache2/keytab/apache.keytab
SetEnvIf Request_URI ^/api noauth=1
<RequireAny>
Require env noauth
Require valid-user
</RequireAny>
FallbackResource /app.php
</Directory>