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>