Сегодня я поделюсь страшным секретом.
Проблема: из фронтенда - Apache в бэкенд - Zope/Plone не проходит
заголовок HTTP. Заголовок - Authorization. Apache делает через
mod_proxy реверсное проксирование запроса к бэкенду - Zope/Plone, при
этом пользователь в Apache уже прошел авторизацию. Но в Zope/Plone
заголовки авторизации уже не попадают. В итоге, узнать был ли
авторизован пользователь и какое его имя в Zope/Plone невозможно.
Полная жопа.
Преамбула.
При разработке сайта, состоящего из фронт-енда и бэк-енда (Apache и
Zope/Plone) столкнулся с неприятной неожиданностью. Схема у меня такая:
Apache принимает все запросы и посредством mod_rewrite и mod_proxy
раздает их по подсистемам, бэкендам. Одна из таких подсистем есть
Zope/Plone. И надо было такому случицца, что в плоне один из разделов
не открытый, а закрытый. Нет проблем, подумал я, урл закрытого раздела
известен, я его закрою Apache-ем. Через директиву Location. Закрыл. И
все бы неплохо, да схема такая больше похожа на затыкание дыры пальцем
- все одно течет. Например, система поиска в Zope/Plone выдает куски
текста из закрытого раздела любому, кто знает, что спросить. Правильное
решение проблемы я отложил на потом, а пока решил очередную дыру
закрыть очередным пальцем.
Я решил, что в скриптах Zope/Plone я буду проверять заголовки HTTP на
предмет наличия признаков прохождения аутентификации. Реально, должен
быть в наличии заголовок Authorization. И/или переменная CGI -
REMOTE_USER. Короче, в скриптах связанных с поиском буду искать эти
заголовки и при их отсутствии отсекать выдачу информации о закрытых
страницах. Изи. И тут я наступил на грабли. О том как эти грабли
прикопать я и песню пою.
Грабли в том, что в Zope/Plone я не могу увидеть заголовки и/или CGI
переменные среды связанные с процессом авторизации протокола HTTP,
созданные Apache-ем. Либо Apache при проксировании режет эти заголовки,
либо Zope/Plone их срубает. На линии браузер-апач заголовки прекрасно
видны, Firebug их замечательно показывает. Подозреваю, что этот, очень
нужный мне заголовок Authorization режут из соображений безопасности.
Трах-их-тибидох.
Решение заключается в том, чтобы передать заголовок нестандартный, с
точки зрения протокола авторизации. Например, скопировать имя
пользователя или вообще весь заголовок Authorization в заголовок с
"левым" именем. В тырнетах я нашел такой пример (у меня не сработал,
возможно потому как у меня в Apache авторизация по методу Digest, а не
Basic), конфига Apache:
nosq.com/blog/2009/07/passing-apache-reverse-proxy-auth-from-windows-to-linux
# (This RewriteRule doesn't actually rewrite anything URL-wise.)
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule .* - [E=RU:%1]
# Put the username into a request header:
RequestHeader set X_REMOTE_USER %{RU}e
Я переработал этот пример в то, что сработало у меня:
SetEnv proxy-chain-auth on
# (This RewriteRule doesn't actually rewrite anything URL-wise.)
# env vars that don't work: AUTH_DIGEST REMOTE_USER REDIRECT_REMOTE_USER
RewriteCond %{HTTP:Authorization} (.+)
RewriteRule .* - [E=XRU:%1]
# Put the username into a request header (zope env var HTTP_X_REMOTE_USER):
RequestHeader set X_REMOTE_USER %{XRU}e
Фишка в том, что RewriteRule ничего не реврайтит а устанавливает
переменную среды и записывает в нее содержимое заголовка Authorization.
А потом RequestHeader-ом я добавляю в request свой левый хидер с
содержимым ранее установленной переменной. И мой левый заголовок
попадает в Zope/Plone!
После чего в Zope/Plone я в любом шаблоне могу получить весь текст
заголовка Authorization и вынуть из него имя пользователя, при
необходимости. Например, таким куском кода:
<span tal:replace="python: request.get_header('HTTP_X_REMOTE_USER', default='oops')">
request header
</span>
Проверено, работает. Теперь и до правильного решения недалеко. Всего-то
надо написать в Zope/Plone User folder, который юзеров берет из этого
моего заголовка.
Сцылки дня:
Комментариев нет:
Отправить комментарий