Новаком
SSO

SSO и MFA для enterprise на Apereo CAS: архитектура, OTP/push и FIDO2

Как построить единый вход и многофакторную аутентификацию в корпоративном контуре на Apereo CAS: поток входа на Spring Web Flow, MFA-подпотоки, политика по приложениям, push/TOTP/FIDO2, сравнение с Keycloak и интеграция со Spring Security.

ЯА
Яковлев Александр
2026-06-28 · 15 минут чтения

Содержание

В крупной организации рано или поздно появляется один и тот же набор болей: десятки внутренних систем, у каждой свой логин, пароли гуляют по стикерам, а служба ИБ не может ответить на простой вопрос — кто, куда и когда заходил. Запрос «что мне делать как единственному ИТ-специалисту, чтобы контора была в информационной безопасности» в наших корпоративных каналах звучит почти дословно. Ответ начинается не с антивируса, а с единой точки аутентификации.

Эта статья — практический разбор того, как строить единый вход (SSO) и многофакторную аутентификацию (MFA) на Apereo CAS в корпоративном контуре: как устроен поток входа, почему MFA правильно делать подпотоками, какие вторые факторы выбирать и как не сломать уже работающие приложения. CAS написан на Java/Spring, поэтому материал особенно полезен командам на Java/Kotlin — а именно с таким стеком мы в Новакоме чаще всего и работаем.

Зачем enterprise отдельный SSO-сервер

SSO решает три задачи одновременно:

  1. Пользователь логинится один раз. Дальше переходы между порталом, CRM, BI и десятком внутренних сервисов идут без повторного ввода пароля — система устанавливает сессию единого входа и выдаёт билет приложению.
  2. Учётные записи живут в одном месте. Не нужно «придумывать способ аутентификации для каждой службы или для каждого приложения» — этим занимается центральный сервер, а приложения только доверяют ему.
  3. ИБ получает единую точку контроля. Все события входа, политика паролей, MFA и аудит сосредоточены в одном узле. Это и есть фундамент, на котором потом строятся PAM, Zero Trust и расследование инцидентов.

Apereo CAS — один из старейших open-source SSO-серверов (изначально Central Authentication Service от Yale). Он поддерживает протоколы CAS, SAML 2.0, OAuth 2.0 и OpenID Connect, то есть умеет быть identity provider'ом и для legacy-систем, и для современных SPA. Для enterprise критично, что это self-hosted решение без обязательной внешней SaaS-зависимости — об этом ниже в разделе про импортозамещение.

Как устроен поток входа в CAS

Ключевая особенность CAS, которую важно понять до внедрения: процесс входа управляется Spring Web Flow. Вся последовательность — от запроса метода аутентификации до выдачи билета и установки SSO-сессии — это управляемый flow с состояниями и переходами.

Упрощённо запрос обрабатывается так:

  1. Приходит запрос на аутентификацию для конкретного сервиса.
  2. CAS проверяет: есть ли уже SSO-сессия? Если да и её достаточно — пользователь сразу переходит к приложению.
  3. Если сессии нет — выбирается ветвь основного метода аутентификации (логин/пароль, LDAP, токен).
  4. После успешной аутентификации CAS генерирует service ticket, устанавливает SSO-сессию и передаёт управление приложению.

Главная мысль архитектуры — не усложнять то, что должно быть простым. Как формулируют сами разработчики CAS: «есть много способов сделать вход очень сложным», и задача сервера — спрятать эту сложность за предсказуемым flow. Приложения, которые уже работают, должны продолжать работать так же: добавление MFA не должно быть «навязчивым принудительным» изменением для каждого клиента.

MFA как подпотоки, а не как «ещё один логин»

Самая частая ошибка при внедрении многофакторки — прикрутить второй фактор как отдельный экран поверх существующего входа. В CAS это решено иначе и гораздо чище: MFA реализуется через подпотоки (subflows) внутри основного flow.

Логика такая. Есть один большой flow, который управляет входом. Внутри него можно ответвляться в более мелкие подпотоки и возвращаться обратно в основной. Аналогия от авторов CAS — съезд с шоссе: вы съезжаете на ответвление, выполняете дополнительную аутентификацию и снова возвращаетесь на основную трассу, где сервер делает то, что делал всегда: генерирует билет и устанавливает SSO.

Это даёт два важных свойства:

  • API не меняется. Если вы писали собственные обработчики аутентификации (authentication handlers), их можно переиспользовать как есть — «взять один и поместить его в MFA-контекст». Не нужно проектировать новые API под каждый фактор.
  • Факторы можно объединять в цепочку. Один подпоток может ответвляться к другому, тот — к третьему. Так из примитивов собирается аутентификация любой строгости: сначала логин/пароль, затем PIN с аппаратного токена, затем биометрия — пока не будет удовлетворено требование политики.
[основной flow: логин/пароль]
        │
        ▼
  нужен MFA? ──нет──▶ выдать ticket, установить SSO ──▶ приложение
        │ да
        ▼
[subflow: второй фактор] ──(цепочка)──▶ [subflow: третий фактор]
        │
        └─▶ вернуться в основной flow ──▶ выдать ticket ──▶ приложение

Практический эффект: вы внедряете MFA точечно — для критичных систем и привилегированных пользователей — не ломая вход в остальные приложения.

Второй фактор: push, TOTP, RADIUS, FIDO2

CAS не навязывает один провайдер второго фактора. На практике в корпоративном контуре встречаются четыре подхода — у каждого свой профиль рисков.

Push-подтверждение. Пользователю прилетает уведомление «подтвердите вход», он жмёт «разрешить». Удобно, но есть известная проблема: пользователи «нередко даже не читают уведомление, просто подтверждают не глядя» — отсюда атаки MFA fatigue (засыпать жертву запросами, пока кто-нибудь не нажмёт «да»). Push без привязки к контексту входа — это удобство в обмен на риск. Классический корпоративный сценарий — push-OTP для доступа по RDP: клиент удалённого рабочего стола запрашивает одноразовый пароль, пользователь оставляет поле пустым, получает push в мобильное приложение и подтверждает отпечатком пальца.

TOTP (коды из приложения-аутентификатора). «Ставите любую офлайн-программу для генерации TOTP-кодов и будет счастье» — Google Authenticator, Яндекс.Ключ, встроенный менеджер паролей. Главные плюсы: работает офлайн, ничего никуда не передаёт, доступен даже без сотовой связи. Минус — код можно невольно ввести на фишинговом сайте, который его тут же перехватит.

RADIUS и собственные провайдеры. Многие организации уже имеют аппаратные токены с собственным провайдером через RADIUS. CAS умеет подключать такие схемы как ещё один способ второго фактора — это позволяет не выбрасывать существующую инфраструктуру токенов. Аналогично интегрируются коммерческие провайдеры вроде Duo: «добавить официальную поддержку конкретного поставщика двухфакторной аутентификации» — частый и хорошо проторённый путь.

FIDO2 / аппаратные ключи. Технология, изначально созданная против фишинга, которую «невозможно обмануть» перехватом кода: секрет привязан к домену и не покидает устройство. В российском контуре сюда относятся, например, носители Рутокен MFA. Это самый строгий из массовых факторов — его стоит требовать для администраторов и доступа к критичным системам.

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

Политика MFA по приложениям и атрибутам

Сильная сторона CAS — декларативная политика второго фактора через реестр сервисов (service registry). Вместо того чтобы зашивать логику в каждое приложение, вы описываете требования централизованно.

Это работает на двух уровнях:

  • По приложению. В реестре сервисов для каждого приложения указывается обязательный метод аутентификации. Когда приходит запрос, «CAS проверяет реестр служб и понимает: вам нужно использовать двухфакторную аутентификацию — давайте сделаем это». Приложению ничего знать про MFA не нужно — оно просто доверяет билету.
  • По атрибуту пользователя. Можно определить, что MFA включается, если определённый атрибут пользователя того требует — например, роль «администратор» или членство в группе с доступом к финансовым данным. Обычные сотрудники проходят базовый вход, привилегированные — усиленный.

Технически распознавание нужного метода устроено через extractor аргументов: компонент разбирает параметр в URL входа и сопоставляет его со списком поддерживаемых методов. Если метод распознан и настроен — CAS уводит пользователя в соответствующий MFA-подпоток; если запрошено что-то неизвестное — система честно отвечает, что не понимает запрос, вместо того чтобы молча пропустить.

Этот подход — основа для перехода к Zero Trust: уровень доверия к сессии определяется не фактом входа, а тем, какие факторы и при каких условиях были пройдены.

Apereo CAS или Keycloak

Два самых частых кандидата на роль self-hosted identity provider в Java-контуре — Apereo CAS и Keycloak. Мы подробно разбирали внедрение Keycloak + Spring Boot отдельно; здесь — короткое сравнение для выбора.

КритерийApereo CASKeycloak
ПроисхождениеCentral Authentication Service (Yale), Java/SpringRed Hat, Java/Quarkus
ПротоколыCAS, SAML 2.0, OAuth 2.0, OIDCOAuth 2.0, OIDC, SAML 2.0
Модель кастомизацииКонфигурация + Java-обработчики, Spring Web FlowРасширения (SPI), темы, REST Admin API
MFAПодпотоки flow, политика по сервисам/атрибутамAuthentication flows, conditional MFA
Где силёнГлубокая интеграция с legacy, тонкая настройка flow, университеты и крупные внедренияБыстрый старт, готовый Admin UI, user federation
Порог входаВыше: нужен опыт SpringНиже: больше «из коробки»

Грубое правило: если у вас много legacy-приложений на протоколе CAS, нестандартные требования к flow и команда с опытом Spring — CAS даёт больше контроля. Если нужен быстрый старт, готовый административный UI и федерация пользователей — обычно проще начать с Keycloak. В обоих случаях это self-hosted решение без обязательной внешней SaaS-зависимости.

Интеграция со Spring Security

Для приложений на Spring подключение к CAS как identity provider'у делается стандартными средствами. Если CAS отдаёт токены по OIDC, на стороне ресурс-сервера это обычный OAuth2 Resource Server:

@Configuration
@EnableWebSecurity
class SecurityConfig {

    @Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeHttpRequests {
                authorize("/actuator/health", permitAll)
                authorize("/admin/**", hasAuthority("ROLE_ADMIN"))
                authorize(anyRequest, authenticated)
            }
            oauth2ResourceServer {
                jwt {
                    jwtAuthenticationConverter = keycloakRolesConverter()
                }
            }
        }
        return http.build()
    }
}

Для веб-приложений с серверным рендерингом подключается spring-security-cas с CasAuthenticationFilter и CasAuthenticationProvider, которые валидируют service ticket на сервере CAS. Важная деталь, вытекающая из архитектуры подпотоков: на стороне приложения логику MFA реализовывать не нужно — приложение получает уже аутентифицированного пользователя с нужным уровнем доверия, а всю работу по факторам выполнил CAS. Это сильно упрощает приложения и убирает дублирование security-кода по сервисам.

Дальше поверх этого выстраивается доменная авторизация: роли из токена, проверки на уровне методов (@PreAuthorize), и при необходимости — связка с темами вроде JWT vs Session, если часть сервисов работает на собственных сессиях.

Импортозамещение и контур без внешних провайдеров

Для российского enterprise отдельный вес имеет то, что CAS полностью разворачивается в собственном контуре. Аутентификация — критичный компонент, и зависеть в ней от внешней SaaS, которая может отключить доступ, рискованно. Self-hosted SSO снимает этот риск: сервер, база, ключи и логи остаются внутри периметра.

Это ложится в общую логику импортозамещения ПО:

  • второй фактор можно строить на отечественных носителях (Рутокен MFA, FIDO2) и российских MFA-сервисах;
  • хранение событий аутентификации и сессионных данных остаётся под контролем — это упрощает выполнение требований 152-ФЗ;
  • нет привязки к зарубежному identity-провайдеру как к единой точке отказа.

При этом миграция на self-hosted SSO — это не «всё и сразу». CAS специально спроектирован так, чтобы существующие приложения продолжали работать без изменений, а MFA включалась точечно. Это позволяет идти поэтапно, без простоя бизнеса.

Как внедрять: этапы и риски

На практике мы рекомендуем такую последовательность:

  1. Инвентаризация. Собрать список приложений, их протоколы (CAS/SAML/OIDC) и текущие способы входа. Часто здесь же выясняется, что часть систем вообще не логируют входы.
  2. Поднять CAS и подключить каталог пользователей (LDAP/AD или его аналог). На этом этапе — только основной фактор, без MFA. Цель — чтобы единый вход заработал и приложения начали доверять серверу.
  3. Подключить приложения по одному. Начать с некритичных, проверить, что SSO-сессия и билеты работают, и только потом двигаться к ключевым системам.
  4. Включить MFA точечно. Сначала — для администраторов и привилегированных ролей через политику в реестре сервисов. Выбрать факторы: FIDO2/аппаратные ключи для верхнего уровня, TOTP/push — для остальных.
  5. Настроить аудит и мониторинг. Все события входа должны писаться и анализироваться — это основа для расследования инцидентов и дальнейшего перехода к Zero Trust.

Типичные риски, которые стоит закрыть заранее:

  • MFA fatigue. Не полагаться на «голый» push — добавлять number matching и контекст входа, а для критичных систем требовать FIDO2.
  • Фишинг одноразовых кодов. TOTP и SMS перехватываются на фишинговых страницах; там, где цена компрометации высока, нужен фишинг-устойчивый фактор.
  • Сломанный вход в legacy. Главная причина провальных внедрений — попытка включить MFA глобально. CAS позволяет этого избежать, но дисциплину «по одному приложению» нужно соблюдать.
  • Восстановление доступа. Заранее продумать процедуру для потерянных токенов, иначе служба поддержки превратится в обходной путь вокруг всей системы безопасности.

SSO и MFA — это не разовый проект, а инфраструктурный слой, который потом несёт на себе PAM, Zero Trust и расследование инцидентов. Поэтому его стоит делать руками команды, которая понимает и Spring, и эксплуатацию в продакшене.

FAQ

Чем двухфакторная аутентификация отличается от двухэтапной? Двухфакторная требует факторов разной природы: что-то, что вы знаете (пароль), и что-то, что у вас есть (токен/телефон) или чем вы являетесь (биометрия). Двухэтапная может использовать два фактора одного типа (например, пароль и контрольный вопрос) — это слабее. На практике крупные сервисы нередко путают эти понятия.

Нужно ли переписывать приложения, чтобы добавить MFA? Нет. В архитектуре CAS второй фактор живёт в подпотоках flow на стороне сервера. Приложение получает уже аутентифицированного пользователя и логику MFA у себя не реализует.

Можно ли подключить уже имеющиеся аппаратные токены? Да. CAS интегрирует существующие схемы через RADIUS и собственных провайдеров второго фактора, а также коммерческие сервисы вроде Duo — это позволяет не выбрасывать инвестиции в токены.

Что выбрать как фактор для администраторов? Фишинг-устойчивый фактор — FIDO2/аппаратные ключи (включая Рутокен MFA). Для привилегированного доступа push и TOTP недостаточно надёжны.

CAS или Keycloak для старта? Если нужен быстрый запуск с готовым админ-UI — обычно Keycloak. Если важны тонкая настройка flow и интеграция с legacy на протоколе CAS — Apereo CAS. Оба — self-hosted и разворачиваются в своём контуре.


Если вы планируете единый вход и многофакторную аутентификацию в корпоративном контуре, мы в Новакоме проектируем и внедряем SSO/MFA на Java/Kotlin-стеке — от архитектуры flow до интеграции со Spring Security и аудита. Посмотрите наши услуги по разработке на Spring и аутстаффингу Java-команд или напишите нам с описанием вашего контура.

РАЗРАБОТКА

Нужна похожая задача?

Обсудим вашу задачу и предложим решение за 30 минут.

Обсудить проект
ЧИТАЙТЕ ДАЛЬШЕ

Похожие материалы.

МЕЖБАНКОВСКИЕ-РАСЧЕТЫ

Межбанковская расчётная система: ностро, лоро и ликвидность на зарубежных счетах

Как устроена межбанковская расчётная система: принцип работы корреспондентских счетов ностро/востро/лоро, клиринг и неттинг (CHIPS, RTGS, SWIFT), способы образования ликвидности на зарубежных счетах — префандинг, FX-свопы, межбанковские кредиты, репо, инкассация — и инженерный взгляд на разработку такой системы.

2026-06-28 · 18 мин
ESP32

ESP32 и mesh-сети: ESP-NOW, ESP-WIFI-MESH, BLE Mesh и Thread/Matter

Серьёзный технический разбор mesh-сетей на ESP32: чем mesh отличается от обычного Wi-Fi, протоколы ESP-NOW, ESP-WIFI-MESH/Mesh-Lite, BLE Mesh и Thread/Matter на ESP32-H2, роли узлов, self-healing, реальные грабли (RSSI, расстояние между узлами, документация) и как выбрать протокол под задачу.

2026-06-28 · 17 мин
NVIDIA-JETSON

NVIDIA Jetson для edge AI: исследование возможностей платформы в 2026

Практический разбор NVIDIA Jetson как платформы edge AI: линейка Orin Nano/NX/AGX, метрика TOPS, реальные бенчмарки (YOLO v8 и локальная Llama 3.2), сравнение с Raspberry Pi, edge против облака, сценарии для роботов, дронов и компьютерного зрения, и когда Jetson реально оправдан.

2026-06-28 · 14 мин