Sso Chronicles: Банк, Жетоны И Немного Волшебства

Привет! Меня зовут Артем Ивлев, и я занимаюсь архитектурой идентификации клиентов банка ВТБ.

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

Для этого существует множество инструментов — и я хочу рассказать о разработке одного из них.

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

Но есть только каталог аккаунтов и отдельные решения для разных команд аутентификации.

У нас еще не было требований, как все должно выглядеть.

При этом мы сразу заговорили об аутентификации физических лиц не только в онлайн-банкинге, но и на партнерских ресурсах.

Та же кнопка «Войти через ВТБ».



SSO Chronicles: банк, жетоны и немного волшебства

Вот как будет выглядеть вход через ВТБ Из этого следовало, что нам нужно взять самое универсальное решение и начать его использовать.

В процессе использования мы могли узнать, что именно нам нужно, каких функций не хватает и т.д. Мы выбираем, по какому пути мы пойдем Порывшись в интернете и покурив магические квадраты Gartner, мы начали искать решения с открытым исходным кодом и поддержкой в России: • Сервер идентификации WSO2 • Кейклоак • ОпенАМ Судя по отзывам в сети и документации, решение от WSO2 с шиной для возможности подключения нескольких провайдеров аутентификации, провайдеров пользовательских данных и т.д. показалось нам наиболее универсальным.



SSO Chronicles: банк, жетоны и немного волшебства

Архитектура сервера идентификации WSO2 Первый прототип мы показали еще в 2019 году на общей демонстрации розничного бизнеса.

Есть серебряная пуля (извини, Брукс) — это символ.

Первое, что мы поняли, это то, что в OAuth 2 лучше всего использовать токен JWT ID, который не требует обращения к серверу аутентификации для проверки при каждом запросе.

Короче говоря, JWT — это пирамида из трёх частей: 1. Заголовок (HEADER) сообщает, что это за токен, как он был подписан и кем выпущен.

2. Тело (PAYLOAD) — набор параметров — позволяет узнать, каким сервисом и для какого пользователя был выдан этот токен, как долго этот токен будет жить.

3. Криптографическая подпись (SIGNATURE) позволяет проверить, что данные в теле токена не были изменены и что токен был выпущен сервером идентификации, которому мы доверяем.



SSO Chronicles: банк, жетоны и немного волшебства

Структура веб-токена JSON (JWT) Все эти части представляют собой одну большую линию, разделенную точками на блоки.

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

Вся информация находится в самом токене.

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

Как добить пулю напильником Токен, выданный на X минут, будет действителен, даже если пользователь нажмет «Выйти» или система безопасности банка получит сигнал о срочном выходе этого пользователя из приложения.

Решение было придумано давно — хранить списки отозванных токенов и проверять их на уровне API Gateway. Да, это тоже сверка с базой данных, но здесь набор значительно меньше и его можно легко реализовать на кэше Redis с помощью TimeToLive. Как мы можем помешать злоумышленникам украсть токен, выданный конкретному мобильному приложению или браузеру пользователя? Ведь технически у пользователя можно что-то украсть из браузера и даже из приложения.

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



SSO Chronicles: банк, жетоны и немного волшебства

Кадр из заставки мультсериала «Симпсоны».

Как обычно, проблема не нова и ее решение «уже было в «Симпсонах» ((с) «Южный парк»).

Создаем безопасный файл cookie (HttpOnly, SameSite, Secure) и помещаем в него UUID. Затем делаем из этого UUID хэш, например CRC32, и помещаем его в тело JWT. Вот и все.

Теперь достаточно при каждом запросе проверять, что хэш от нашего cookie равен написанному в теле токена.

Безопасный файл cookie труднее украсть, поэтому пара токен-файл cookie дает нам достаточную уверенность.

Адаптивная аутентификация, или Почему нам пришлось пойти своим путем В процессе входа пользователя в систему задействовано много дополнительной магии.

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

Это задача адаптивной аутентификации.

И, с одной стороны, использование модуля позволяло вводить все эти задачи с помощью скриптового интерфейса WSO2 IS, но, с другой стороны, невозможно было реализовать красивый API для мобильных устройств или SPA. Дело в том, что вся адаптивная аутентификация происходит на уровне сервера по мере генерации интерфейсов с помощью JSP. Это сложно адаптировать даже для современной веб-разработки, не говоря уже об API для мобильного приложения.

После первых прототипов и попыток адаптировать универсальность под пожелания коллег с мобильных и веб-платформ, мы поняли, что эту часть придётся переписывать.

Для мобильного приложения и онлайн-банкинга мы решили реализовать всю логику, используя всего один хендл API/oauth2/токена — в зависимости от входящих параметров он выдает токен или ошибку с просьбой перейти к нужному шагу второго фактора.

запрос.

Мы решили реализовать бизнес-логику непосредственно в Grant_type — параметре /oauth2/token, который отвечает на вопрос о требуемом типе аутентификации.

В результате мы получили стройную логику.

Есть поставщик услуг — потребитель аутентификации.

Имеет настройки, в том числе набор типа гранта.

Таким образом, мы прекрасно понимаем, кто и под какими логинами может к нам зайти.

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

WSO2 IS слишком много читает и записывает в базу данных.

Нам пришлось заново переписать часть логики генерации токенов.

Сессии были удалены из PostgreSQL в Redis. Это снизило нагрузку на основание на порядок.



SSO Chronicles: банк, жетоны и немного волшебства

Комментарии не нужны :) Но, как оказалось, этого тоже недостаточно.

Зависимость от самой базы для такого критического сервиса – далеко не лучшее решение.

Если база данных падала или становилась недоступной (где в основном хранятся настройки и выданные токены, мы уже удалили оттуда сессии), мы не могли пустить пользователя в банк.

Добавлена проверка, если база данных недоступна - выдавать токены в экстренном случае, если их невозможно продлить через пять минут. То есть пользователи по-прежнему смогут работать в приложении банка — но только пока жив первый выпущенный токен.

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

Ну и последний гвоздь в коде выпуска токенов — решение полностью переписать остатки WSO2 IS. Последняя версия вообще больше не взаимодействует с базой данных во время аутентификации пользователя.

Остается только Redis, в котором хранятся сеансы аутентификации, JWT и выданные в них токены обновления.

Что дальше? Новые горизонты Когда токен будет выпущен, от вендора WSO2 IS останется так мало, что вскоре мы сможем перейти от монолита, который может делать слишком много, к микросервисам, которые могут делать только то, что нам нужно, и с той производительностью, которая нам нужна.

Теперь у нас есть доступ к банковскому приложению в мобильной и веб-версии.

Но этого недостаточно.

Ведь у ВТБ есть много других продуктов.

Это «Мультибонус», «ВТБ Мобайл» и десятки, если не сотни других наших проектов.

Все требуют аутентификации и единой точки входа.



SSO Chronicles: банк, жетоны и немного волшебства

Кадр из мультсериала «Рик и Морти» А еще очень много внешних партнеров и поставщиков, которые, конечно, будут только рады «четким» пользователям с паспортом и другими данными.

Поэтому мы работаем над единым логином ВТБ.

Это даст пользователю возможность максимально безопасно и удобно идентифицировать себя в каршеринге, страховке, стриминге или «Рогах и Копытах» (согласитесь, проще нажать на кнопку «Войти через ВТБ», чем брать фото паспорта и введите данные вручную).

А для потребителя аутентификации ВТБ это очень удобный способ идентифицировать и предоставить данные пользователя в соответствии с федеральным законодательством.

Эпилог Прошел почти год с тех пор, как наши первые релизы пошли в производство.

Решение развивается и приобретает новые возможности.

Разве мы не должны были сразу же начать писать свои собственные? Была ли вообще необходима WSO2? История не терпит сослагательного наклонения, но я думаю, что в условиях крайне сжатых сроков и итеративной разработки нам, скорее всего, ничего не удалось бы сделать - а даже если бы и удалось, то это не дошло бы до наших стандартов и не имело бы позволили нам развиваться дальше.

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

ЗЗЫ: О чем вы хотите прочитать в следующий раз? Аутентификация, биометрия или цифровой профиль и использование Tarantool Data Grid? Теги: #информационная безопасность #oidc #аутентификация #vtb #SSO #oauth2 #wso2

Вместе с данным постом часто просматривают: