У меня есть Apache, работающий как обратный прокси за внутренним сервером. Пользователи, поражающие прокси, обязаны использовать клиентские сертификаты. На внутреннем сервере существует веб-приложение, которое может использовать HTTP-заголовок для аутентификации пользователей. Я хотел бы иметь прокси, предоставляют тот заголовок на основе клиентского сертификата.
Значение заголовка является идентификатором пользователя. Идеально у меня был бы текстовый файл, отображающий идентификатор пользователя на сертификат. Рядом как я могу сказать, мне нужно RewriteMap
но для заголовков.
# Somehow lookup USERID given SSL_CLIENT_S_DN
RequestHeader set X-User-ID %{USERID}
Я хотел бы избежать целого набора SetEnvIf
s требование сервера перезапускает для изменения, например:
SetEnvIf SSL_CLIENT_S_DN [User 1's SSL_CLIENT_S_DN] USERID=12
SetEnvIf SSL_CLIENT_S_DN [User 2's SSL_CLIENT_S_DN] USERID=34
SetEnvIf SSL_CLIENT_S_DN [User 3's SSL_CLIENT_S_DN] USERID=56
...
Существует ли хороший способ, которым я могу избежать пользователей от необходимости по существу пройти проверку подлинности дважды?
Думаю, я понимаю, что вам нужно, но, пожалуйста, поправьте меня, если я ошибаюсь. Для этого требуется трехэтапный подход.
Вы используете RewriteCond
с RewriteMap
для сопоставления SSL_CLIENT_S_DN
с USERID
, a RewriteRule
для установки переменной среды, а затем директива RequestHeader
для установки заголовка на основе переменной среды. Это должно привести к тому, что заголовок будет нормально передан на внутренний сервер.
Что-то вроде:
RewriteEngine On
# Define a RewriteMap for DN to user id
RewriteMap dntouserid "txt:/path/to/dntouserid.txt"
# Test if we have something in the map for a the current DN
RewriteCond ${dntouserid:%{SSL:SSL_CLIENT_S_DN}} (.+)
# Set environment variable based on that mapping. %1 comes from the RewriteCond
RewriteRule ^ - [E=MYUSER:%1]
# Set header to that environment variable
RequestHeader set X-User-ID %{MYUSER}e
А затем ваша карта содержит строки вроде:
DN_OF_USER1 12
DN_OF_USER2 34
DN_OF_USER3 56
Если DN содержит пробелы, вам придется использовать внешнюю программу для выполнения map, а не в виде обычного текстового файла (он может работать для других типов карт, но я не пробовал).