Как мы реализовали авторизацию пользователей ALD Pro через Keycloack на примере Grafana
Один из наших заказчиков пришел к нам с запросом по комплексному импортозамещению — требовалось организовать переход на новую службу каталогов. В качестве основного решения по замене была выбрана система ALD Pro. Но по ходу проработки решения мы столкнулись с рядом сложностей. Самые большие из них были связаны с заменой компонентов AD FS и публикацией веб-сервисов с помощью WAP. В этом посте рассказываем, как мы решали эту задачу.
Основная связка, на которой мы собирали альтернативную схему, представляла собой Keycloack для авторизации и NGINX для балансировки запросов. В ходе проекта использовались реальные системы заказчика, но для тестирования мы выбрали синтетическую систему на базе Grafana — для эмуляции.
Чтобы понять, что к чему, посмотрим на схему нашего кейса. Цифрами обозначена последовательность прохождения запросов-ответов от клиента и обратно для авторизации в Grafana.
Схема сетевого взаимодействия синтетического пилотного сегмента ALD Pro
Клиент и все серверы находятся в домене ALD Pro.
Задача следующая: клиенту на PC (172.99.27.12) необходимо авторизоваться и получить доступ к ИС (Grafana, 172.99.26.22) в домене ALD с помощью сервиса Keycloak (172.99.26.21). При этом клиент находится в другой подсети. В качестве прокси-сервера используется NGINX с двумя сетевыми интерфейсами.
Давайте поэтапно пройдемся по настройке всех компонентов.
1. Подключение Keycloak к ALD Pro LDAP
Далее представлена пошаговая настройка для варианта с ALD Pro LDAP.
Переходим в меню: adrealm→ User federation → Add new provider → LDAP.
Ниже пример настроек группового маппера для ALD.
После настройки необходимо проверить корректность с помощью меню: Action→ Sync LDAP groups to Keycloak.
2. Настройка авторизации для клиентских приложений
На этом этапе мы ориентировались на инструкцию из статьи на Хабре: Keycloak. Админский фактор и запрет аутентификации (кейс № 2).
Ниже итоговые настройки браузерного потока (они отличаются от предложенных в статье). В процессе настройки потока мы пришли именно к такому порядку шагов:
3. Настройка Keycloak для связки с Grafana
В консоли Grafana переходим в меню → Clients → Create client.
Далее создаем клиента как на рисунках ниже.
Потом переходим в настройки созданного клиента на вкладку Credentials, сохраняем Client Secret. Он понадобится в дальнейшем при настройке со стороны клиентского приложения.
Копируем endpoint-ссылки, куда будет обращаться Grafana для аутентификации пользователей. Для этого переходим в меню → Realm settings → OpenID Endpoint Configuration.
Нас интересуют те, которые оканчиваются на auth, token, userinfo.
4. Запуск Keycloak
Основная настройка заключается в параметре запуска сервиса Keycloak:
/opt/keycloak/keycloak-22.0.1/bin/kc.sh start --hostname aldbln01.int:1024
--http-relative-path /key --hostname-admin-
url=https://aldbln01.int:1024/key/
Если после запуска команды kc.sh start Keycloak попросит выполнить сборку с новыми параметрами, то необходимо выполнить команду: */kc.sh build.
Параметр --hostname означает url, по которому будет работать Keycloak. В параметре --hostname устанавливаем имя нашего прокси-сервера (NGINX) и порт, который он будет прослушивать (aldbln01.int:1024).
Параметр --http-relative-path должен совпадать с названием локации в NGINX (в нашем случае /key), из которой будет работать сервис.
Параметр --hostname-admin-url требуется для доступа к админской консоли. Задаем вручную ее url (https://aldbln01.int:1024/key/).
5. Настройка NGINX
Устанавливаем NGINX из репозитория с помощью команды apt install nginx -y (в нашем стенде ОС Astra SE 1.7.4). В директории etc/nginx/sites-enabled переносим или переименовываем стандартный файл конфигурации, а затем создаем в нем новый файл aldbln.conf. Ниже описание конфигурации в файле aldbln.conf:
server {
listen 80;
listen 1024 ssl default_server;
ssl_certificate /etc/nginx/Cert.pem;
ssl_certificate_key /etc/nginx/Key.pem;
server_name aldbln01.ald.int;
location /key {
proxy_pass https://aldkeycl01.ald.int;
}
location /grafana/ {
proxy_pass http://aldweb01.ald.int:3000;
}
}
Для работы по протоколу https достаточно выпустить ключ и самоподписанный сертификат на его основе.
Для работы с Grafana прослушиваются http 80 и https 1024 порты (порт 1024 взят для теста, по умолчанию можно использовать 443). Запрос пользователя перенаправляется (proxy_pass) на доменное имя Grafana web01:3000 (при указании в адресе запроса http (s):// nlb/grafana).
Пример: https://aldbln01.ald.int/grafana.
Для Keycloak также прослушиваются http 80 и https 1024 порты (порт 1024 взят для теста, по умолчанию можно использовать 443) и перенаправляется в локацию (/key), если такой путь присутствует в http-запросе.
Пример: https://aldbln01.ald.int/key.
6. Настройка Grafana
Все настройки Grafana прописываются в конфигурационном файле /etc/grafana/grafana.ini.
Добавляем раздел с OAuth-аутентификацией в любое место (но не в середину другого раздела). В примере он расположен сразу после секции [server]):
#exampleHeader1 = exampleValue1
#exampleHeader2 = exampleValue2// конец раздела server, копировать не нужно
########ADDED FOR KEYCLOAK############
[auth.generic_oauth]
enabled = true
scopes = profile email openid
email_attribute_path = email
login_attribute_path = username
name_attribute_path = full_name
oauth_allow_insecure_email_lookup = true
name =Keycloak-OAuth
tls_skip_verify_insecure = true
allow_sign_up = true
client_id = grafana2
client_secret = OEHvGwD***********8vHb
auth_url = https://aldbln01.ald.int/realms/adrealm/protocol/openid-connect/auth
token_url = https://aldkeycl01.ald.int/realms/adrealm/protocol/openid-connect/token
api_url = https://aldkeycl01.ald.int/realms/adrealm/protocol/openid-connect/userinfo
__________________________________________
Параметр scopes проверяет области из KeyCloak. Доступные области можно
посмотреть в административной консоли KeyCloak в разделе "Client scopes"
*_attribute_path — пути к атрибутам, которые будет проверять Grafana. При
кастомных названиях можно поменять их в соответствии с названиями атрибутов в KeyCloak.
Параметр client_id должен соответствовать ID клиента в KeyCloak.
Параметр client_secret — необходимо вставить тот секрет, который сохраняли ранее
*_url — скопировать точные ссылки на endpoint, которые ранее видели в KeyCloak.
...
domain = aldweb01.ald.int
...
http_port = 3000
...
root_url = http://aldbln01.ald.int/grafana/
...
serve_from_sub_path = true
...
auth_url = https://aldbln01.ald.int:1024/key/realms/adrealm/protocol/openid-connect/auth
token_url = https://aldkeycl01.ald.int/key/realms/adrealm/protocol/openid-connect/token
api_url = https://aldkeycl01.ald.int/key/realms/adrealm/protocol/openid-connect/userinfo
...
signout_redirect_url = https://aldbln01.ald.int:1024/key/realms/adrealm/protocol/openid-connect/logout?post_logout_redirect_uri=http://aldbln01.ald.int/grafana&client_id=grafana2
__________________________________________
Параметр domain — прописать имя хоста, где работает сервис grafana.
Параметр http_port должен соответствовать тому, который указан на прокси сервере Nginx.
Параметр root_url — из него Grafana генерирует redirect url при запросе в KeyCloack,
а как мы помним пользователь находится в другой подсети, так что здесь
указывается «прокси» имя.
Параметр serve_from_sub_path задается, чтобы Grafana могла работать из
локации /grafana. (как в нашем примере)
Параметр auth_url — та ссылка, по которой Grafana перенаправит пользователя
для аутентификации и ввода логина/пароля. Так что она должна проксироваться.
Параметр token_url ,api_url — бэковые endpoint, по которым Grafana будет обращаться
напрямую в Keycloack. Скопировать их из OpenID endpoint из консоли
администратора Keycloack.
Параметр signout_redirect_url (если что, это все одна строка) — ссылка, по которой
Grafana перенаправит пользователя, когда он нажмет кнопку signout. Чтобы успешно
попасть на форму логаута в KeyCloack, затем вернуться в Grafana (а не застрять
в межинтернетном пространстве) и проксировать оба адреса.
Также важно внести изменения в секцию Server, т. к. настройки по умолчанию будут редиректить на localhost. Необходимо не только записать нужное значение, а также убрать »;» в начале строки.
[server]
# Protocol (http, https, h2, socket)
protocol = http
# This is the minimum TLS version allowed. By default, this value is empty.
Accepted values are: TLS1.2, TLS1.3. If nothing is set TLS1.2 would be taken
;min_tls_version = ""
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
# The http port to use
http_port = number of your port
# The public facing domain name used to access grafana from a browser
domain = yourhostname.example.com
# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false
# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
Далее нужно сохранить все изменения и перезагрузить Grafana. На странице входа должна появиться новая кнопка с OAuth-аутентификацией:
7. Проверка работы
По адресу прокси /grafana должна открыться консоль Grafana с сервера aldweb01. Остается нажать кнопку «Sign in with Keycloak».
Откроется страница аутентификации, которая указана в настройках Grafana (auth_url). Далее вносим учетные данные пользователя ALD Pro.
Благодаря параметру root-url в настройках Grafana Keycloak успешно вернет пользователя назад в Grafana уже авторизованным. Теперь осталось нажать кнопку «Выйти из аккаунта».
Grafana переведет по ссылке, которая указана в параметре signout_redirect_url.
Выход произведен успешно! Ура!
Вместо заключения
В этой статье мы рассмотрели только основной костяк решения. Для боевых внедрений надо настраивать кластер балансировщиков, реализовывать роуминг VIP-адресов, выбирать метод балансировки между бекэндами. Сам Keycloak необходимо реализовывать в режиме высокой доступности, но это уже детали.
На выходе мы получили решение, которое помогло разобраться с основной задачей. Появилась возможность публиковать корпоративные сервисы c использованием службы единого входа. Это позволяет нашим заказчикам переходить на импортозамещенные службы каталогов, в частности, ALD Pro, и при этом не беспокоиться за работу сервисов, которые с ней интегрированы.
Это решение и многие другие можно детально посмотреть на нашем стенде импортозамещения.
Инженер-проектировщик вычислительных комплексов
Инженер внедрения отдела биометрических технологий и систем аутентификации