Централизованное управление аутентификацией и авторизацией в инфраструктуре с помощью OpenID Connect

изображение: grok
При инвентаризации IT-инфраструктуры любой современной компании системный администратор с высокой вероятностью увидит разрозненный набор различных бизнес- и инфраструктурных сервисов: каждый из них живёт по своим правилам; часть используется почти каждым сотрудником на ежедневной основе, а некоторые – в разы реже. Управление учётными записями, паролями и процессом аутентификации и авторизации в таких условиях превращается в настоящий квест.
- Не просрочился ли пароль у пользователя?
- А где хранится пароль?
- Не заблокировалась ли учётная запись?
- Не избыточны ли права, выданные конкретной учётной записи?
Все эти вопросы являются постоянной головной болью отдела эксплуатации и сопровождения пользователей. К счастью, существуют решения класса Identity Provider (IdP), которые позволяют централизовать процесс аутентификации и в большинстве случаев авторизации за счёт подключения к таким сервисам как можно большего числа корпоративных информационных систем (ИС).
В данной статье мы разберёмся, как один из самых популярных протоколов аутентификации и авторизации OpenID Connect (OIDC) помогает осуществить такую централизацию, рассмотрим, как и куда можно его подключить, и при этом постараемся не привязываться к конкретному решению.
Перед детализацией того, что и как можно подключить к OpenID Connect, стоит узнать, что это такое. OIDC – это надстройка, реализующая процесс аутентификации (подтверждения личности) над протоколом OAuth 2.0, который решает задачу авторизации (выдачи прав доступа к ИС от имени пользователя).
На схеме ниже представлен упрощенный процесс взаимодействия пользователя, клиента, IDP и целевой ИС:

Теперь, когда мы получили высокоуровневое понимание работы OIDC, имеет смысл немного углубиться в то, какие токены использует данный протокол. Всего их три:
- ID Token – это токен формата JWT, содержащий так называемые claims (метаданные) о личности пользователя: в них входят логин пользователя, его почта, группы, служебная информация (когда и кем был выпущен токен) и прочее. Данный токен служит чем-то вроде цифрового паспорта пользователя.
- Access Token – короткоживущий токен, который служит для доступа к целевым ИС. Именно его клиент передаёт целевой ИС для подтверждения прав доступа. Мы можем изменять содержимое токена на стороне IdP, например, добавлять свои поля и значения, если этого требует целевая ИС.
- Refresh Token – долгоживущий токен, который позволяет автоматически обновлять Access Token без необходимости повторной аутентификации.
Рассмотрим основные термины, с которыми мы можем столкнуться при работе с OpenID Connect:
- flow – поток авторизации, например, Authorization Code Flow, являющийся стандартом для Single-Page Application-сервисов, таких как GitLab и Grafana, или Client Credentials Flow, который может пригодиться, если понадобится машинная авторизация между сервисами;
- redirect_uri – адрес целевой ИС, с которой будет происходить перенаправление на IdP;
- scope – параметр запроса, который определит, какой набор данных о пользователе запросит клиент OIDC;
- client_id и client_secret – публичный идентификатор и приватный ключ, которыми пользуются целевая ИС и IdP для работы по OIDC.
Переходим к самому интересному – внедрению IdP и подключению к целевым ИС. Для того чтобы централизовать процесс аутентификации и авторизации информационных систем, нам нужно сначала эти информационные системы определить.
Сегодня нашими подопытными будут:
- GitLab в роли внутреннего сервиса разработки с нативной интеграцией;
- Proxmox-кластер в качестве примера интеграции только в части аутентификации;
- Grafana в роли инфраструктурной сущности, которую мы можем интегрировать как в части аутентификации, так и в части авторизации;
- Корпоративный портал собственного производства, написанный на C# (.NET), в роли приложения, которое мы можем научить работать с OIDC внутренними силами;
- 1С в роли критичной бизнес-системы, которая поддерживает OIDC лишь частично.
Первым шагом будет развёртывание IdP в нашей инфраструктуре: это может быть как open-source-решение, например Keycloak, Dex, Authentik, Authelia или Hydra, так и что-то отечественное, например Цифровой Купол. Вариантов реализации довольно много; при выборе стоит учитывать требования к масштабируемости и производительности, количество одновременно работающих пользователей и общее количество пользователей, а также требования регуляторов (152-ФЗ, нормативные правовые акты ФСТЭК России, необходимость в использовании сертифицированного решения).
Мы справились с первым шагом, и теперь наш IdP развёрнут по адресу idp.company.com; для теста создано несколько пользователей. Мы готовы перейти ко второму этапу – его интеграции с нашими ИС.
Начнём с наиболее простого варианта – GitLab. Предположим, что наш GitLab развёрнут в рамках нашей инфраструктуры по адресу https://gitlab.company.com, для того чтобы интегрировать его с IdP, нам потребуется создать клиент на стороне IdP и добавить в него нашего пользователя. В клиенте мы задаём client_id и client_secret, а также redirect_uri, после чего мы вносим данные параметры в конфигурационный файл GitLab, и после перезагрузки появляется кнопка входа через OIDC. Нажав на неё, пользователь будет переадресован на IdP для ввода учётных данных. После успешной аутентификации пользователь вернётся в GitLab автоматически и сможет продолжить стандартный рабочий процесс. Уточню, что в GitLab также есть функционал по маппингу групп для реализации авторизации из OpenID Connect, но данный функционал доступен только в платных версиях данной ИС.
Следующая система на очереди – Proxmox; здесь интеграция повторяет процесс с GitLab, но управление правами реализовано исключительно на стороне самого Proxmox. Поэтому повторяем процесс с созданием клиента, конфигурацией OIDC на стороне ИС и получаем уже вторую систему, подключённую к IdP.
Теперь перейдём к красивым дашбордам в Grafana и к тому, как мы можем защитить их от несанкционированного редактирования. Обычно в Grafana создаётся несколько сервисных учёток, и рано или поздно их учётные данные попадают во внутреннюю базу знаний в открытом виде либо записываются в текстовые файлы на рабочих столах всех, кто когда-либо туда заходил. Чтобы этого избежать, создадим новый клиент в нашем IdP и настроим авторизацию. Grafana станет первым сервисом, в котором мы будем это делать. Для настройки авторизации на стороне IdP мы создадим claims, которые помогут Grafana определить, какие привилегии у входящего пользователя. Ролевая модель Grafana довольно простая: нам достаточно создать claim с названием role и указать возможные значения: Admin, Editor и Viewer. Если IdP по умолчанию не использует claims в качестве ролей, стоит также явно донастроить это. По итогам данного этапа мы получаем систему визуализации Grafana с ролевой моделью и единым входом, что позволяет чётко разграничить привилегии и закрыть вопрос безопасности аутентификации и авторизации.
Мы уже рассмотрели несколько примеров интеграции с решениями, в которых OIDC работает «из коробки»; теперь поговорим про то, как его внедрить в наш корпоративный портал, о котором говорилось выше. Так как портал написан на .NET, мы можем взять готовую библиотеку для OIDC (в целом это справедливо почти для любого языка программирования; подробнее с готовыми реализациями можно ознакомиться здесь. С подключённой библиотекой разработчику остаётся внести небольшие изменения в обработчик запросов, сделав так, чтобы они учитывали OIDC, и настроить подключение к нашему IdP. Данные изменения, как правило, не требуют существенных доработок.
Теперь в нашей копилке целых 4 решения, использующих централизованный подход. Следующая ИС на очереди – 1С. В случае 1С стоит сразу сказать, что поддержка OIDC здесь появилась нативно начиная с версии платформы 8.3.22, но доступна только для тонкого, веб- и мобильного клиентов, так что, если в организации используется толстый клиент, пользователей придётся перевести на тонкий или веб-клиент.
После проведения всех вышеперечисленных интеграций мы получаем единое место для управления учётными записями, но что это нам даёт с точки зрения удобства?
Приведу список:
- Единая учётная запись в IdP вместо набора, который требуется сопровождать;
- Возможность централизованно применить парольную политику организации вместо попыток настроить всё в каждой ИС отдельно;
- Возможность включить технологию единого входа (single sign-on / SSO); таким образом, пользователи, аутентифицированные в одном клиенте IdP, смогут войти в другие ИС без необходимости повторной аутентификации (это настраиваемый процесс и при корректной настройке позволяет повысить качество использования различных ИС пользователями, не снижая уровень безопасности);
- Возможность использовать мультифакторную аутентификацию, например Kerberos, SMS/e-mail/TOTP-коды, мобильное приложение и прочие варианты; также мы можем комбинировать их, предъявляя разные требования по количеству факторов и их сложности для разных клиентов;
- Блокировка пользователя во всех ИС разом при увольнении или инциденте ИБ вместо блокировки в каждой из ИС по отдельности.
Подводя итоги, хочу сказать, что системы класса IdP и протоколы OpenID Connect и OAuth 2.0 позволяют создать централизованное решение, закрывающее вопросы безопасности аутентификации и авторизации в рамках инфраструктуры компании, а популярность протоколов позволяет интегрировать их с минимальными издержками и сложностью.

Автор: Аверин Андрей Александрович, старший инженер по ИБ, компания Digital Design.



