Keycloak для нас – центральная система авторизации и аутентификации всех внешних и внутренних пользователей. Мы «подружили» ее с другими системами и сервисами, гоняли с различными нагрузками, и хотим поделиться общим впечатлением.

Далее рассказ про то, как у нас все устроено под капотом, а также плюсы и минусы работы с Keycloak, которые мы подметили за последние два года.

Меня зовут Константин Белкин, я Teamlead SRE в РСХБ-Интех. Данный пост – переработанная версия моего доклада с RSHB Identity Management Meetup, который мы провели в феврале. Если нужны подробности по этому мероприятию или видеозапись – все это можно найти по ссылке.

Задачи авторизации, которые надо решить в банке

Давайте пробежимся по списку проблем и задач, связанных с авторизацией и аутентификацией в больших банках. Я бы выделил шесть основных.

1. Проблема децентрализации. В банке много программных продуктов, и у каждого – свой слой авторизации и аутентификации. Одни хранят данные рядом в БД, другие заходят по LDAP в Active Dirtectory, третьи еще как-то. Это все надо унифицировать.

2. Хранение данных пользователя. Главный вопрос – как правильно хранить данные и как их передавать.

3. Шифрование. Где-то используется LDAPS, где-то незащищенный LDAP. И эту проблему тоже надо решить.

4. Межсервисная интеграция. Чтобы «подружить» две различные системы, надо написать интеграционный адаптер, что требует финансовых затрат. Эта проблема будет возникать снова и снова по мере появления в активе новых систем.

5. Блокировка пользователей. Если какая-то из систем не обменивается данными с центральными системами (у нас в банке используются IDM, Active Directory), она не сможет получить информацию, что определенного пользователя надо отключить, когда тот ушел в отпуск или уволился. Раньше такие системы имели отдельных администраторов, к которым приходилось обращаться лично.

6. Затраты на интеграцию. В отсутствии единой точки обмена затраты будут расти, поскольку каждая система должна интегрироваться с другими смежными системами. И для каждого случая нам приходилось писать интеграционные адаптеры и где-то их размещать.

Чем может помочь Keycloak?

С Keycloak появляется единый центр авторизации и аутентификации: для пользователей банка, клиентов банка, систем банка и сервисов банка, находящихся в рамках различных систем. 

Появляются единые стандарты безопасности и аналитики, а также единая панель управления для сотрудников службы безопасности, которую они смогут подключить к своим системам для получения данных и отслеживания внештатных ситуаций, например, когда под одним аккаунтом пытаются зайти много раз.

С Keycloak стандартизируются политики безопасности для проверки и анализа данных. Плюс, появляется инструмент выдачи прав всему слою систем для банковских администраторов. Благодаря этому администратор одной системы может быстро заменить администратора другой системы. У него будет тот же интерфейс и тот же набор данных, но обслуживаться будет другая ролевая модель.

Теперь несколько слов о нашей банковской платформе App.Farm и то, как центр аутентификации и авторизации с ней связан.

Как устроена наша банковская платформа App.Farm

App.Farm – это банковская среда, следующая концепциям PaaS. Тут есть конвейер непрерывного развертывания, системы интеграции, контроля доступа и публичная витрина приложений.

Платформенная архитектура App.Farm хорошо накладывается на организационную структуру банка и то, как мы подходим к разработке банковских продуктов. 

Основа оргструктуры РСХБ-Интех – это Блоки. Блоками называются большие подразделения в компании, в которых есть отделы, называемые центры компетенций (ЦК). ЦК, в свою очередь, управляют конкретными банковскими системами.

Аналогичную структуру мы воссоздаем внутри нашей платформы. Кроме нее есть подсистемы, где хранятся ресурсы и ролевые модели для каждой системы. Системы вне App.Farm тоже имеют право авторизовываться у нас и идентифицировать своих пользователей. В итоге мы получаем единый слой авторизации для прохода пользователя по всем системам.

Например, сотрудник пришел на работу и залогинился в систему А, после чего он может ходить по всем системам. Ему не нужно реаутентифицироваться в браузере, чтобы зайти в систему Б или В, при условии, что такое поведение предусмотрено соответствующей ему ролью.

Архитектура платформы построена на Kubernetes, поскольку технология предоставляет наилучший опыт отказоустойчивости и масштабирования. Если нам не хватает мощностей, мы можем масштабировать наш Keycloak, добавив к нему реплик или процессоров для этих реплик.

Постройку платформы с Keycloak начали около двух лет назад. Изначально она объединяла три проекта. Первый – интеграционная платформа, где системы объединяются и обмениваются данными. Второй – CI/CD, потому как нам надо было поставлять туда платформенные адаптеры и продукты, которые мы разрабатываем, а еще дать другим продуктам в нашем цикле разработки поставлять на эту платформу ПО. В итоге у нас появился проект CI/CD как сервис.

Потом появился третий проект – OpenAPI, в рамках которого мы открываем наши API для внешних компонентов. Например, Банки.ру хотят знать, где у нас находятся банкоматы. Им нужно регулярно подключаться по API и забирать эту информацию. Другой пример – это подключение к органам ФНС и обмен данными.

А потом к нам пришел проект SSO, и у нас появился вот такой Вольтрон на основе сущностей, которые мы объединили между собой.

Фундамент платформы – декларативность и открытость. Платформу строили на модели Infrastructure as Code. Все описываем в GitLab, который является базой для CI/CD. Мы всегда все описываем декларативно, и на основе местоположения репозитория (Блок-ЦК-Система) создается специальный проект, который называется «информационная система» – сокращенно isys.

isys:
  name: "Электронные площадки"
  description: "Информационная система для доступа к Электронным площадкам"
  owner: "ЦК Электронных площадок"
  cpuLimits: "52"
  cpuRequests: "32"
  ramLimits: "70656Mi"
  ramRequests: "39936Mi"
  roles:
    - code: "cbr-open-api"
      description: "Роль для использования сервисов ЦБР OpenAPI"
    - code: "esia-user"
      description: "Роль для использования сервиса авторизации через ЕСИА"

У проекта isys есть название, краткое описание, потребляемые или разрешенные ресурсы. И здесь же декларативно описывается ролевая модель, а дальше ее подхватывает самописная сущность – оператора Kubernetes.

Вся платформа у нас построена на операторах Kubernetes, которых сейчас четыре. Один из них называется auth-оператор, он создает и управляет сущностями Keycloak. Platform-operator считает ролевой манифест (на иллюстрации выше), пойдет в Keycloak и создаст клиента этой информационной системы. Затем назначит ему необходимые роли, чтобы потом можно было этими ролями управлять, а администратор системы мог назначать их каким-то пользователям или другим системам для входа.

Обзор клиентских функций Keycloak

Начну с публичных клиентов. Они аутентифицируют, авторизуют, определяют роль и предоставляют определенный для нее интерфейс. Например, если пользователю назначена роль админа, интерфейс будет админский. Все это можно описать в программе на основе библиотеки Keycloak, которая поставляется практически под каждый язык. 

Единственный минус публичного клиента – отсутствующая возможность обратиться к другим сервисам или системам, потому как у публичного аккаунта отсутствует сервис-аккаунт, о котором поговорим отдельно.

Другой тип – это конфиденциальные клиенты. Они обладают тем же самым набором данных, который мы видели до этого. В их функции и задачи входит создание сервис-аккаунтов. Это опциональная функция, но мы ее всегда используем.

Давайте посмотрим на схему.

Тут есть источник данных – Active Directory, откуда берет информацию Keycloak. Вы можете управлять различными типами и мапперами и получать действительно богатый набор данных. Внутренний пользователь может аутентифицироваться как во внутренние системы, которые находятся внутри платформы, так и во внешние системы. Помимо этого, у нас есть DMZ-слой, где находится второй Keycloak для внешних пользователей – наших клиентов. 

Теперь обо всем этом подробнее.

Пользовательские паттерны: внутренний пользователь (сотрудник банка)

В этом случае информацию о пользователе мы получаем строго из Active Directory – это для нас информационный центр. В свое время служба безопасности ограничила нам добавление новых пользователей «руками», поэтому всю информацию мы вытягиваем из AD, и новые пользователи создаются только там.

Мы все понимаем, что всем нам нужны технические пользователи для взаимодействий, мы эту проблему решаем через Platform-Operator. Он создает клиента и включает функцию сервис-аккаунта, которого вы потом используете для вашей системы.

Для каждого сервиса и каждой системы мы заводим собственный сервис-аккаунт. Помимо этого, у нас есть возможность интеграции пользователей с нашим внутренним банковским Identity-менеджером. Это нужно для того, чтобы руководитель мог управлять ролями своего подчиненного. На основе этих данных мы можем назначать созданные в Keycloak роли пользователю, который входит в ту или иную группу. Соответственно, чтобы получать информацию о состоянии, постоянно синхронизируемся с Active Directory. У Keycloak несколько паттернов синхронизации, которые вы можете использовать. Один из них – временной паттерн, который мы используем для синхронизации раз в три часа. А полную синхронизацию проводим раз в неделю.

Пользовательские паттерны: клиент банка

В данном случае Keycloak будет являться объединяющим центром хранения клиентских учетных записей. Мы можем спокойно хранить довольно большие объемы обезличенных данных: телефоны, емейлы. Информация о пользователях содержится во внутренней банковской системе CDI, где каждому пользователю присваивается уникальный идентификатор. На основе телефона и емейла мы всегда можем подтянуть из CDI его ФИО. Таким образом закон о персональных данных не нарушается, поскольку телефон и емейл сами по себе не подпадают под него, потому что нет сопоставления с ФИО.

Персонального идентификатора достаточно, чтобы сообщить другой системе, что это именно этот пользователь. В итоге мы предоставляем единую точку входа для всех клиентов за счет одного реалм-слоя. Если клиент банка зашел на одну из наших площадок, например, в «Своё Село» или «Своё Родное», хочет купить там продукты, то после он может спокойно проходить по всему слою всех экосистем «Своё».

Теперь расскажу про платформу и Keycloak, и как там у нас все работает.

Жизненный цикл клиентов: клиент внутренней системы (ISYS)

Это клиенты, которые несут информацию о ролях. Они всегда будут публичными клиентами, если система имеет точку входа, и могут быть конфиденциальным, если это слой каких-то API-эндпоинтов, которые он предоставляет другим системам. 

Клиент умеет определять набор пользовательских данных, который будет предоставлен при авторизации пользователя у данной системы. Также клиент несет индивидуальные настройки времени жизни токена. Мы можем задать хоть 15 минут, и заставлять пользователя реаутентифицироваться по истечении очередной сессии.

Жизненный цикл клиентов: клиент внутреннего сервиса (PSVC)

Следующий тип клиентов – клиент внутреннего сервиса (PSVC – Platform Service). Он используется для авторизации в других системах, т.е. обладает сервис-аккаунтом. На сервис-аккаунт даются роли, таким образом он может обратиться к какому-то другому сервису, чтобы пройти у него авторизацию и аутентификацию и получить какие-то данные от него. 

Клиент внешней системы (EXSYS) – это системы, которые находятся за пределами нашей платформы. Они обладают таким же набором ролей, как ISYS.

Платформенный сервис, находящийся в системе, может спокойно подключаться к другим информационным системам или общаться с внешними информационными системами для обмена данными. Все это позволяет вам получить Keycloak в одном реалм-слое.

Сервис-аккаунты, и как мы их готовим

Оператор управляет созданием ролевых сущностей в Keycloak. На основе этого у нас создаются клиенты платформенного сервиса, использующиеся для авторизации. Клиент имеет название самого аккаунта и его секрет. Работает это так: получили токен, пошли, получили необходимые данные. На сервис-аккаунт мы назначаем роли, чтобы представиться сервисам и получить от них данные. 

Внешним внеплатформенным сервисам мы предоставляем тот же набор функций и также декларируем по модели IAC. У нас есть потребители в банке, которые используют эту модель. Часть из них – внутренние системы, имеющие внешний слой. Они идут как публичные – это «Свое Фермерство», «Свой Бизнес».

Кроме того, мы в k8s используем любимую разработчиками технологию ISTIO. В процессе разработки ISTIO позволяет избежать подключения к центру аутентификации и не тратить время на встраивание компонентов безопасности, как, например, spring-security. А также не настраивать его на работу с центром авторизации, OIDC-клиентом. Вы просто отлаживаете приложение и пишете манифест, как на примере ниже, что вы защитили эндпоинт таким-то ролями, метод такой-то.

psvc:
  name: "Скрининг ПС: bff"
  description: "Скрининг ПС: Backend for frontend"
  roleMapping:
    - endpoint: /api/baseDictionaries/search/getByBaseDictionaryTypeCodeAndCode
      roles:  admin,developer,auditor-sva,user-dkk2,user-dkk1,user-controller-dkk
      methods: GET
      zones: external
    - endpoint: /api/baseDictionaries/search/getByBaseDictionaryTypeCodeAndCode/*
      roles:  admin,developer,auditor-sva,user-dkk2,user-dkk1,user-controller-dkk
      methods: GET
      zones: external

Пришедший пользователь попадает на ISTIO Sidecar. Если он не аутентифицирован и не авторизован, то пройти никуда не сможет. Таким образом разработчик может делать системы без отладки подсистемы безопасности внутри, переложив эту функцию на ISTIO, что сокращает время вывода продукта на рынок.

Внешнее SSO и зачем оно нам было нужно

SSO-модуль для внешних пользователей используется для сквозных переходов, чтобы пользователь не аутентифицировался в десяти разных системах, а зашел один раз и пошел по всему слою, а также для использования двухфакторной авторизации.

В рамках внешнего SSO у нас возник проект, который называется RSHB ID. Он аналогичен Sber ID или Tinkoff ID, которые позволяют клиенту банка аутентифицироваться на каких-то других платформах. Например, на mos.ru за счет тех данных, которые ему передаст наш SSO-провайдер.

Общая схема с внешним SSO выглядит так:

Она включает в себя ряд появившихся внешних клиентских сервисов и большую экосистему «Своё». Тут достаточно сложный алгоритм работы, основанный на YAML-манифестах, которые приезжают в Kubernetes и обрабатываются оператором. На их основе создаются сущности как внутри, так и снаружи.

Идентично внутреннему SSO у нас есть оператор внешних сущностей, управляющий созданием клиентов Keycloak по декларативной модели. Также оператор управляет ролями во внешнем Keycloak и в случае наличия клиентов публичной системы создает у нас еще одну сущность под названием PUBSYS. Эта сущность несет ролевую модель, которую можно наложить на пользователей, чтобы пользователь авторизовывался и аутентифицировался под какими-то конкретными данными.

Также тут есть отдельный механизм управления сетевой доступностью для внешних клиентов на основе ISTIO. Он стоит перед входом как шлюз и аутентифицирует клиентов, если это необходимо для прохождения во внутреннюю сеть банка.

Keycloak накладывает много ограничений на операторов. Система не гибкая, и в рамках энтерпрайза приходится дописывать дополнительные модули. Мы написали два плагина, использующиеся внутри Keycloak. Это интеграционный модуль для вытягивания из системы CDI идентификаторов пользователей и совмещения их с номерами телефонов для получения соответствий. И модуль двухфакторной аутентификации с нашим отдельным SMS-центром, находящимся в процессинговом центре и обслуживающим клиентов банка.

Плюсы Keycloak

  • Это opensource с большим комьюнити. В данный момент Keycloak является стандартом в индустрии. Если есть задача сделать центр авторизации для вашего приложения, то Keycloak – прекрасный выбор. Он обладает расширенным API, что позволяет дорабатывать и адаптировать его под свои нужды. 

  • С Keycloak вы получаете единый центр авторизации и аутентификации для разных систем, где есть поддержка общепризнанных моделей на выбор: OIDC, SAML, OAUTH.

  • Также он обладает федеративностью. Это значит, что вы можете «заключить соглашение» об обмене пользователями с большим числом систем, начиная от Active Directory и заканчивая LDAP.

  • Keycloak может стать посредником в передаче данных. Особенно это актуально для задач перехода с одного LDAP-каталога на другой ввиду требований отказа от Active Directory и перехода на какой-то opensource, например FreeIPA. Keycloak заберет себе необходимые данные и передаст в другую систему.

  • Еще один плюс – это скорость обработки. Он может работать с миллионами пользователей одновременно. Какие-то проблемы с нагрузкой могут начаться, после миллиона, а до 100 или 500 тыс. одновременных пользователей – вообще никаких проблем.

Для проверки скорости работы мы создали скрипт, который на первом прогоне входил 20 раз в секунду, а во втором – 40. В итоге отставание по времени между двумя этими прогонами составило 8 секунд после четырехчасового эксперимента. Это отличный показатель.

Наибольшая реальная нагрузка у нас – это 50 входов в секунду. Система работает на трех инстансах, каждый из которых имеет два CPU и 4 ГБ памяти. Плюс, база на Postgres. При этом нагрузки на Postgres очень низкие, что получается за счет кэша в памяти, которым обладает Keycloak.

Минусы Keycloak

  • Первый минус – это opensource. 

  • Обязательно потребуются доработки, если вы сидели на LDAP и запланировали переход на какую-то другую модель авторизации.

  • Для энтерпрайза всегда требуются доработки и расширение API, так как стоят задачи интеграции в существующие системы.

  • Еще один минус по части доработок – отсутствие полноценной документации к API. Вам придется читать много кода, чтобы что-то доработать. Перебирать похожие плагины, изучать их код и на его основе создавать свои.

  • Отсюда вытекает следующий минус – всегда придется лезть в код.

  • В Keycloak есть места, где можно что-то нажать, и все сломается. У нас было такое, пришлось восстанавливать базу. Можно случайно удалить какую-то объединяющую роль, и придется все строить с начала.

  • Как следствие, всегда нужна тестовая зона для проведения экспериментов. На это уходят дополнительные ресурсы.

FAQ

Прежде чем подвести итоги, помещу сюда ответы на некоторые вопросы с митапа, которые могут оказаться полезными коллегам, присматривающимся к Keycloak.

Целесообразно ли использовать Keycloak для небольших систем?

Для системы с одним пользователем это не имеет смысла, а когда пользователей набралось с десяток, уже можно попробовать. Со своей собственной авторизацией можно провозиться дольше, чем с Keycloak. Благодаря отличной документации к пользовательской части Keycloak можно настроить за день, и он будет прекрасно работать.

Насколько безопасно использовать внешний продукт для аутентификации? Как быстро правятся уязвимости?

В opensource ты можешь самостоятельно закрыть уязвимости. Вдобавок Keycloak поддерживается компанией Red Hat, а они исправляют все быстро.

Шифруем ли мы jwt-token’ы, которые гуляют по системе?

Да. Из коробки Keycloak предоставляет несколько шифровальных алгоритмов, которые мы используем для внутреннего и внешнего SSO.

Предположим, в одном приложении пользователь входит по логину и паролю, во втором по номеру телефона и SMS, а в третьем по паролю и двухфакторной авторизации, это будут разные пользователи?

Один. Просто в каждом клиенте на вход будут настроены разные наборы клиентских данных.

Краткие выводы

Тут много позитива, потому пробегусь по лишь основным моментам. Keycloak может стать надежной системой входа энтерпрайз-уровня для всех типов пользователей, будь то клиенты банка или внутренние сотрудники. Он может решить интеграционные задачи и стать надежным центром предоставления доступа и обмена данными между разными системами. Keycloak может стать единой точкой входа для всех ваших программных продуктов. Но, все это с учетом тех оговорок, которые я упомянул в разделе минусов.

Комментарии (3)


  1. Dmitry2019
    00.00.0000 00:00
    +2

    Спасибо, очень хорошая статья. Мы сами где-то год назад внедрили KeyCloak и находим все больше и больше плюсов используя этот продукт.

    В наши приложения мы добавили авторегистрацию в кейклоке, чтобы новый клиент при деплое сам смогзарегистрироваться и залить все роли, которые он поддерживает.


    1. pr0l
      00.00.0000 00:00

      вы смогли организовать 2fa авторизацию в keycloak или это сделали отдельно в приложении?(не смс, а модное сейчас через телегу например)


      1. Dmitry2019
        00.00.0000 00:00
        +1

        Люди настолько против 2фа, что клиент не захотел этого делать. А фот SSO зашло с удовольствием