Я работаю над устаревшим приложением PHP, работающим на Symfony v3 на Apache 2.4. Это приложение защищено аутентификацией 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 в мой vhost таким образом:
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
И мне не удается применить мой LocationMatch к этому новому URI.
Я заперт. Как я могу получить доступ к своему устаревшему приложению, защищенному Kerberos, и опубликовать мой API без аутентификации?
Наконец-то решил.
Первая проблема, использование mod_rewrite перенаправить на фронт-контроллер находится в директиве Directory. Директивы каталога обрабатываются перед директивами Location, поэтому мой URL переписывается перед моей директивой Location. Так что мой API-адрес стал /app.php/api
и часть после имени скрипта не может быть отфильтрована с помощью директивы Location. Как упоминалось в Книге Symfony, я заменил переписывание URL-адреса командой Apache FallbackResource, которая делает то же самое (перенаправляет на мой фронт-контроллер Symfony), но это возможно для фильтрации на моем /api
URL с директивой Location … так что это должно было быть возможно использовать <LocationMatch "^((?!/api).)*$">
,
Но вторая проблема, с которой я столкнулся, заключается в том, что LocationMatch (или Location ~
который, кажется, делает то же самое) работает на «позитивную перспективу», как ^/api
но, похоже, есть ошибка в Apache 2.4.10 (может быть, из-за модуля Kerberos), когда я использую «негативную перспективу», как /(?!api)
, Содержимое директивы LocationMatch обрабатывается даже для /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>
Других решений пока нет …