Проектирование и внедрение централизованного сервиса аутентификации (login‑service)

Устали от множества паролей? Разбираем архитектуру Login‑Service: SSO, MFA, OAuth и OIDC для безопасного доступа к сотням приложений.

Цель статьи – показать, как спроектировать и реализовать централизованный сервис аутентификации (login‑service), который будет безопасно обслуживать десятки и даже сотни внутренних и внешних приложений․ Мы разберём архитектурные подходы, протоколы (SAML, OAuth 2․0, OpenID Connect), вопросы безопасности (MFA, защита токенов) и практические шаги внедрения․


Почему нужен единый login‑сервис?

  • Удобство для пользователей․ Один ввод пароля → доступ к множеству приложений․
  • Снижение нагрузки на ИТ․ Управление учётными записями происходит в одном месте․
  • Повышение безопасности․ Меньше точек входа → проще контролировать MFA, аудит и реагировать на инциденты․
  • Гибкость интеграции․ Современные протоколы позволяют подключать как облачные, так и on‑premise‑сервисы․

Эти преимущества описаны в публикациях Хабр и Контур․Эгида, где подчёркивается роль Identity Provider (IdP) и Service Provider (SP) в модели SSO․

Основные протоколы единого входа

  1. SAML 2․0 – XML‑ориентированный протокол, широко используется в корпоративных решениях․ Позволяет передавать утверждения (assertions) о пользователе от IdP к SP․
  2. OAuth 2․0 – протокол авторизации, часто комбинируется с OpenID Connect для аутентификации․
  3. OpenID Connect (OIDC) – надстройка над OAuth 2․0, передаёт JWT‑токены с информацией о пользователе (ID‑token) и позволяет реализовать self‑service portal как единый вход․

Выбор протокола зависит от:

  • Требований к совместимости с существующими приложениями;
  • Наличия готовых библиотек/SDK;
  • Уровня требуемой безопасности (например, SAML часто используется в банковском секторе)․

Архитектура эффективного login‑сервиса

Ниже представлена типичная схема, адаптированная под современные требования:

+-------------------+ +-------------------+ +-------------------+
| Пользователь | ----> | Front‑End (UI) | ----> | Identity Provider|
+-------------------+ +-------------------+ +-------------------+
 | |
 | (SAML / OIDC / OAuth) |
 v v
 +-------------------+ +-------------------+
 | Auth Service | | User Directory |
 | (Token Issuer) | | (LDAP/AD/DB) |
 +-------------------+ +-------------------+
 | | Token (JWT / SAML Assertion)
 v
 +-------------------+
 | Service Provider |
 | (Приложения) |
 +-------------------+

Ключевые компоненты:

  • Front‑End (UI) – страница входа, поддерживает адаптивный дизайн и интеграцию с MFA․
  • Identity Provider (IdP) – центральный сервер, который аутентифицирует пользователя и выдаёт токены․
  • Auth Service – микросервис, генерирующий JWT, управляет сессиями, проверяет revocation‑list․
  • User Directory – хранилище учётных записей (LDAP, AD, PostgreSQL, NoSQL)․
  • Service Provider (SP) – любые подключаемые сервисы (веб‑приложения, API, мобильные клиенты)․

Пошаговое руководство по построению login‑сервиса

Планирование и аудит

  1. Соберите список всех приложений․ Разделите их на категории: облачные, on‑premise, мобильные, API‑ориентированные․
  2. Определите поддерживаемые протоколы․ Для старых систем часто нужен SAML, для новых – OIDC․
  3. Анализ требований к MFA․ По данным Хабр, обязательный второй фактор уменьшает количество точек входа и повышает безопасность․
  4. Оцените текущие каталоги пользователей․ Если уже есть AD/LDAP, лучше использовать их в качестве источника данных․

Выбор стека технологий

Компонент Рекомендуемые решения Плюсы
Identity Provider Keycloak, Gluu, Microsoft Entra ID, Google Workspace (OIDC) Поддержка SAML, OIDC, MFA, UI‑кастомизация
User Directory OpenLDAP, Microsoft AD, PostgreSQL + Hasura Гибкая схема, возможность репликации
Auth Service (Token) Node․js (express‑jwt), Go (golang‑jwt), Java (Spring Security) Лёгкая интеграция с микросервисами
MFA Provider Authy, Duo, Google Authenticator, YubiKey Поддержка TOTP, push‑уведомлений, WebAuthn

Реализация IdP

Пример настройки Keycloak под OIDC (по материалам Google Workspace):


kcadm․sh create realms -s realm=corp -s enabled=true

kcadm․sh create clients -r corp -s clientId=my-app 
 -s enabled=true -s publicClient=false 
 -s redirectUris='["https://my-app․example․com/callback"]' 
 -s protocol=openid-connect

kcadm․sh update realms/corp -s "otpPolicyType=totp" 
 -s "otpPolicyAlgorithm=HmacSHA1" -s "otpPolicyDigits=6"

После создания клиента получаем client_id и client_secret, которые передаём в конфигурацию приложений․

Интеграция сервисов‑провайдеров

Для веб‑приложения на Node․js + Express используем библиотеку passport-openidconnect:

const passport = require('passport');

const OIDCStrategy = require('passport-openidconnect')․Strategy;

passport․use('oidc', new OIDCStrategy({
 issuer: 'https://idp․example․com/auth/realms/corp',
 authorizationURL: 'https://idp․example․com/auth/realms/corp/protocol/openid-connect/auth',
 tokenURL: 'https://idp․example․com/auth/realms/corp/protocol/openid-connect/token',
 userInfoURL: 'https://idp․example․com/auth/realms/corp/protocol/openid-connect/userinfo',
 clientID: 'my-app',
 clientSecret: 'SECRET',
 callbackURL: 'https://my-app․example․com/callback',
 scope: 'openid profile email'
}, function(issuer, sub, profile, accessToken, refreshToken, done) {
 // Здесь можно создать/обновить локального пользователя
 return done(null, profile);
}));

app․get('/login', passport․authenticate('oidc'));
app․get('/callback', passport․authenticate('oidc', { failureRedirect: '/' }), (req, res) => {
 res․redirect('/');
});

Для сервисов, работающих только с API, достаточно проверять JWT‑токен в заголовке Authorization: Bearer <token> и использовать библиотеку jsonwebtoken для валидации подписи․

Реализация MFA

Согласно рекомендациям Multifactor, лучше использовать push‑уведомления или WebAuthn вместо только TOTP․ Пример интеграции с Duo:

POST https://api․duosecurity․com/auth/v2/auth
Headers:
 Authorization: Basic BASE64(client_id:client_secret)
Body (x-www-form-urlencoded):
 username=user@example․com
 factor=push
 device=auto

Ответ содержит txid, по которому клиент может опрашивать статус аутентификации․

Управление сессиями и отозвание токенов

  • Храните refresh‑token в защищённом HttpOnly‑cookie․
  • Ведите revocation list в Redis: при выходе пользователя из системы или блокировке учётки добавляйте jti токена в список и проверяйте его при каждом запросе․
  • Устанавливайте короткое время жизни access‑token (5‑15 мин) и более длительное для refresh‑token (30‑90 дней)․

Мониторинг и аудит

Для обеспечения соответствия требованиям (GDPR, ISO 27001) необходимо вести журнал событий:

  1. Успешные и неуспешные попытки входа․
  2. Запросы MFA и их результаты․
  3. Создание/удаление/изменение учётных записей․
  4. Отзыв токенов․

Интегрировать можно с ELK‑stack или Splunk через syslog‑вывод из IdP․

Лучшие практики безопасности

  • HTTPS везде․ Даже внутренние запросы к IdP должны идти по TLS․
  • Контроль CORS․ Отключайте wildcard‑домены, указывайте только доверенные источники․
  • Content Security Policy (CSP) – защита от XSS при внедрении UI‑страницы входа․
  • SameSite=Strict для cookies, чтобы предотвратить CSRF․
  • Регулярный аудит сертификатов и ключей․ Используйте автоматическую ротацию (Let’s Encrypt, Vault)․
  • Защита от brute‑force․ Ограничьте количество попыток входа per IP/username, используйте CAPTCHA․
  • Zero‑Trust подход․ Даже после аутентификации проверяйте права доступа на каждый запрос (RBAC/ABAC)․

Пример полного рабочего цикла

  1. Пользователь открывает https://login․example․com → UI запрашивает логин/пароль․
  2. IdP проверяет учётные данные в LDAP и инициирует MFA (push‑уведомление)․
  3. После подтверждения генерируется JWT access‑token (подписанный RS256) и refresh‑token․
  4. Токен сохраняется в HttpOnly‑cookie session и в локальном хранилище (для SPA)․
  5. При запросе к микросервису GET /api/orders клиент отправляет заголовок Authorization: Bearer <access‑token>․
  6. Сервис проверяет подпись токена, срок действия и отсутствие jti в revocation‑list․
  7. Если токен просрочен, клиент использует refresh‑token для получения нового access‑token через эндпоинт /auth/refresh․
  8. Все события (логин, MFA, токен‑рефреш) записываются в ELK‑stack для последующего аудита․

Часто задаваемые вопросы (FAQ)

Можно ли использовать один IdP для разных доменов?

Да․ Большинство решений (Keycloak, Azure AD, Google Workspace) поддерживают мульти‑тенант конфигурацию: отдельные Realms/Projects для каждого домена․

Как мигрировать существующие пароли?

Рекомендуется использовать hash‑migration: при первой попытке входа пользователь вводит старый пароль, система проверяет его по старому хешу, а затем сохраняет пароль уже в современном алгоритме (bcrypt/argon2)․

Что делать, если приложение не поддерживает SSO?

Можно внедрить reverse‑proxy (например, Nginx + lua‑script) который будет перехватывать запросы, проверять JWT и передавать их в приложение как заголовок X-User․

Создание эффективного login‑сервиса – это комбинация правильной архитектуры, выбора протоколов (SAML, OIDC), внедрения многофакторной аутентификации и строгих практик безопасности․ Следуя описанным шагам, вы получите:

  • Единый вход для всех сервисов;
  • Гибкую интеграцию с существующими системами;
  • Повышенную защиту от утечек учётных данных;
  • Полный аудит и возможность масштабирования․

Помните, что успех проекта зависит от тщательного планирования и постоянного мониторинга․ Регулярно обновляйте компоненты, проверяйте уязвимости и обучайте пользователей безопасному использованию MFA․


Статья составлена на основе актуальной информации (SAML, OIDC, MFA) из публикаций Хабр, Google Workspace, Multifactor и других источников по состоянию на ․