Коллега порекомендовал мне опубликовать это из StackOverflow в ServerFault:
Это сводит меня с ума. У меня есть веб-приложение, которое обслуживается через веб-сервер Apache. Сервер базы данных, поддерживающий приложение, - это Apache CouchDB, который предоставляет HTTP API для получения документов и потоковых вложений.
Я защитил базу данных CouchDB, предоставив объект безопасности, который позволяет только определенным пользователям получать доступ к данным в базе данных и возвращает 401 для анонимных запросов к конечным точкам HTTP.
Я хочу иметь возможность сопоставлять общедоступные URL-адреса с вложениями документов, хранящимися в этой базе данных. Итак, я попытался создать правило перезаписи в моем файле .htaccess, которое проксирует запросы с определенных URL-адресов непосредственно на CouchDB, жестко кодируя учетные данные пользователя, например:
## DOWNLOAD STREAM:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://user:pass@127.0.0.1:5984/database/$1 [P]
В идеальном мире приведенный выше пример должен принимать следующий URL:
http://example.com/download/UUID/attachment.ext
И проксировать его на:
http://user:pass@127.0.0.1:5984/database/UUID/attachment.ext
Этот метод действительно передает запрос в CouchDB, но опускает компонент userinfo схемы URI. Итак, запрос обрабатывается как анонимный, и я получаю ошибку 401. Вложение передается только в том случае, если я удалю защиту из базы данных.
Я потратил пару часов на чтение конфигурации Apache и безрезультатные эксперименты. Поиск в Интернете бесполезен из-за всех связанных запросов с похожими ключевыми словами.
Как я могу гарантировать, что mod_rewrite включает имя пользователя и пароль, указанные в правиле перезаписи, когда он проксирует CouchDB?
Я понял! Вместо того, чтобы включать имя пользователя: пароль как часть схемы URI, заголовок авторизации должен быть установлен независимо. Следующее решение полностью работает в .htaccess
файл, что важно, поскольку OS X периодически сдувает настройки внутри сайтов VirtualHost:
SetEnvIf Request_URI ^/download/* ADD_COUCH_BASIC_AUTH
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=ADD_COUCH_BASIC_AUTH
## DOWNLOAD STREAM
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://127.0.0.1:5984/database/$1 [P]
Как это работает: мы используем SetEnvIf
чтобы проверить, соответствует ли путь запроса пути, который мы хотим проксировать, и если да, установите произвольную переменную среды ADD_COUCH_BASIC_AUTH
В следующей строке мы добавляем заголовок Basic Auth к исходящему запросу, только если установленная нами переменная среды существует. Таким образом, основной заголовок аутентификации будет добавлен только при запросе ресурса через /download/
, таким образом отправляя учетные данные аутентификации в CouchDB.
Примечание: вам нужно будет кодировать Base64 ваше имя пользователя: пароль и учетные данные и заменить XXXXXXXXXXX
с закодированным значением. Простой способ сделать это на Mac:
echo -n 'user:pass' | openssl base64
Надеюсь, это поможет кому-нибудь, кроме меня!