Аутентификация через SSO

В этой статье:

Примечание

Функции SSO реализованы в виде модуля com.universe.mdm.sso.kerberos, который является примером использования SSO. Некоторые шаги могут отличаться в зависимости от используемой инфраструктуры.

Модуль com.universe.mdm.sso.kerberos поставляется отдельно в виде собранных jar-файлов. Для включения функций SSO необходимо добавить 4 jar-файла в папку ./universe-integration. См. подробнее о добавлении кастомных модулей.

Исходники SSO:

Скачать com.universe.mdm.sso.kerberos-6.9.0-SNAPSHOT-sources.jar

Скачать com.universe.mdm.sso.kerberos-6.9.0-SNAPSHOT.jar

Зависимости для Spring:

Скачать spring-security-kerberos-core-1.0.1.RELEASE.jar

Скачать spring-security-kerberos-client-1.0.1.RELEASE.jar

Общие сведения

Основные участники

Основные участники:

  • Client - клиентский компьютер, который хочет пройти аутентификацию на сервере (Web Server).

  • Web Server - сервер, который предоставляет сервис клиенту, в данном случае сервер с universe web app.

  • KDC - Key Distribution Center - центральный узел Kerberos (в случае Windows Server - Domain Controller), который состоит из двух компонентов:

    • Authentication Server - сервер аутентификации.

    • Ticket Granting Server (TGT) - сервер выдачи тикетов пользователю.

Основные понятия:

  • Key Distribution Center (KDC) - хранилище информации о паролях пользователей.

  • Admin server - основной сервер kerberos. У нас KDC и admin server находятся на одной машине

  • Realm - домен, в котором производится аутентификация.

  • Principal - пользователь, участвующий в механизме аутентификации.

  • Keytab - файл таблицы ключей, содержащий пары имен субъектов Kerberos и зашифрованные ключи, полученные из пароля Kerberos.

  • krb5.conf - настройки KDC в Universe web app.

Ускоренный курс по Kerberos:

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

Фактически KDC имеет свой собственный ключ и другие ключи для пользователей домена.

В процессе аутентификации пользователя в web-сервере нет взаимодействия между web-сервером и KDC в Windows Domain Controller.

../../../_images/sso1-2.png

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

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

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

../../../_images/sso1-3.png

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

../../../_images/sso1-4.png

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

Полезные ссылки:

Механизм аутентификации

Механизм аутентификации

Предусловия:

  • Пользователь успешно аутентифицирован на машине под управлением Windows.

  • Ссылка на ресурсы universe (Url) не может быть в виде ip:port, а только с указанием DNS-имени (связано с регистрацией Web-сервиса в AD).

Предупреждение

БД Universe должна быть синхронизирована с AD через LDAP

Шаги аутентификации:

  1. Пользователь открывает ссылку на ресурс universe с указанием get параметра sso со значением on или true (например, universe-ea?sso=true).

  2. Сервер universe возвращает HTTP-код 401 "Not Authorized".

  3. Браузер пользователя запрашивает токен в KDC.

  4. AD возвращает токен.

  5. Браузер отправляет запрос на аутентификацию пользователя в universe, в запросе присутствует полученный токен.

  6. Сервер валидирует токен в KDC. В случае успеха сервер получает имя пользователя в AD.

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

Настройка окружения

Имена хостов

Каждый сервер внутри Kerberos realm должен иметь FQDN (Fully Qualified Domain Name).

Kerberos так же ожидает, что FQDN сервера является reverse-resolvable. Если выяснение доменного имени по IP недоступно, то установите значение переменной rdns в значение false на клиентах в файле krb5.conf.

Если сервер уже имеет назначенное FQDN, проверьте корректность обнаружения forward и reverse, выполнив на клиенте следующие команды:

$ nslookup dc.use.me
$ nslookup "Ваш IP"

Наличие соединения

Для проверки соединения между хостами, выполните ping для каждого хоста по его FQDN:

$ ping dc.use.me
PING dc.use.me (10.0.0.1) 56(84) bytes of data.
64 bytes from dc.use.me (10.0.0.1): icmp_seq=1 ttl=128 time=0.176ms

Вывод команды ping показывает успешное определение IP-адреса по FQDN, и простой ответ от сервера. Ответ от сервера является подтверждением того, что между хостом и сервером есть соединение.

Проблемы при работе ping указывают на проблемы настройки сервера или клиента.

Синхронизация времени

Протокол Kerberos требует синхронизации времени сервера и клиента: если системные часы клиентов и сервера расходятся, то аутентификация не будет выполнена. Простейший способ синхронизировать системные часы - использование Network Time Protocol (NTP) сервера.

Для настройки допустимого расхождения времени в krb5.conf предусмотрен параметр clockskew.

Брандмауэры

Так же как и все остальные сетевые службы, Kerberos должен иметь возможность проходить через любые брандмауэры между хостами. Инструкция Kerberos System Administration Manual имеет детальное описание портов, которые необходимо открыть при настройке брандмауэров.

Настройка Windows Domain Controller with KDC

Шаг 1. Создать пользователя для сервера приложений, который будет выполнять роль ServicePrincipal.

Первоначально пользователь создается с логином und, логин меняется на HTTP/universe.use.me@USE.ME после создания.

../../../_images/sso3.png ../../../_images/sso4.png

Шаг 2. Создать маппинг пользователя на сервис командой setspn в cmd в режиме Администратора:

$ setspn -A HTTP/universe.use.me und

Шаг 3. Сгенерировать .keytab файл и поместить его на сервер приложений (Universe):

$ ktpass /out c:\tomcat.keytab /mapuser und@USE.ME /princ HTTP/universe.use.me@USE.ME /pass Qwerty123 /ptype KRB5_NT_PRINCIPAL /crypto All

Предупреждение

@USE.ME прописывается в верхнем регистре даже если при конфигурировании указывался нижний регистр

Шаг 4. Настроить допустимые encryption types: Group Policy Management → Default Domain Policy → Computer Configuration → Windows Settings → Security Settings → Local Policies → Security Options → Network security: Configure encryption types allowed for Kerberos.

../../../_images/sso5.png

Шаг 5. Hostname сервера universe должен быть reverse-resolvable для Windows AD Server. Проверяется с помощью команды nslookup.

Если это не так, должна быть создана запись Host A в DNS → Forward Lookup Zones и pointer в Reverse Lookup Zones.

../../../_images/sso6.png

В Windows AD Server можно настроить аудит для Kerberos (Настройка Kerberos аудита в AD).

Настройка Windows клиентов

Необходимо настроить браузер IE/MS Edge на каждом клиенте в Свойствах Браузера.

Шаг 1. Разрешить встроенную проверку подлинности Windows.

../../../_images/sso7.png

Шаг 2. Настроить местную интрасеть.

../../../_images/sso8.png ../../../_images/sso9.png ../../../_images/sso10.png

Шаг 3. Ссылка на ресурсы universe (Url) не может быть в виде ip:port, а только с указанием DNS-имени (связано с регистрацией Web-сервиса в AD). При невозможности использовать DNS, маппинг должно быть прописан в файле C:WindowsSystem32driversetchosts.

Пример:

10.30.218.25 universe.use.me

Шаг 4. Время должно быть должно быть синхронизировано с AD и веб-сервером universe. Настройка браузеров для использования с Kerberos.

Настройка Universe web app

  1. Время должно быть синхронизировано с Windows AD Server.

  2. Скопируйте keytab сгенерированный во время настройки Windows AD Server на сервер с tomcat.

  3. Скопируйте krb5.conf на сервер с tomcat.

    • Realm - доменное имя большими буквами.

    • Дополнительно см. в файле krb5.conf

Пример krb5.conf:

[libdefaults]
      default_realm = USE.ME

[realms]
      USE.ME = {
               kdc = dc.use.me
      }

[domain_realm]
      use.me=USE.ME
      .use.me=USE.ME
  1. В universe должно быть реализован модуль со следующими сущностями:

    • Interceptor запросов, который перехватывает запросы пользователя и отвечает схемой "401 Negotiate" для получения KDC тикета от пользователя и валидирует пришедший тикет.

    • KerberosSecurityDataSource реализует SecurityDataSource, AfterModuleStartup, который регистрирует провайдеры аутентификации, авторизации и получения профиля для SSO через Kerberos, либо делегирует дефолтному компоненту.

    • Необходимые провайдеры для SSO через Kerberos, зарегистрированные в KerberosSecurityDataSource, например LoginProvider.

    • Сервис, осуществляющий поиск пользовательских атрибутов по имени пользователя (через LDAP или в локальной бд, если она синхронизирована с AD).

  2. Tomcat должно быть запущен с опциями.

Пример:

-Djava.security.krb5.conf=/path/to/krb5.conf
-Dsun.security.krb5.debug=true //for debug only, remove when all works
  1. Должны быть предоставлены необходимые свойства для валидации пришедшего тикета.

Пример свойств в backend.properties:

security.kerberos.realm=USE.ME //edit with correct domain name
security.kerberos.keytab.file=/path/to/tomcat.keytab
security.kerberos.service.principal=HTTP/universe.use.me@USE.ME
  1. FQDN должно быть reverse-resolvable. Если выяснение доменного имени по IP недоступно, то установите значение переменной rdns в значение false в файле параметров krb5.conf.

Если сервер KDC уже имеет назначенное FQDN, проверьте корректность обнаружения forward и reverse выполнив на клиенте следующие команды:

$ nslookup dc.use.me
$ nslookup "Ваш IP"

Вывод первой команды должен содержать IP-адрес сервера. Вывод второй команды должен содержать FQDN сервера.

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

Предупреждение

После ip сначала должно быть fqdn.

Пример:

#Правильно
10.21.1.178   dc.use.me   use.me

#Неправильно
10.21.1.178   use.me      dc.use.me

После этого проверьте работу локальных DNS имен используя команду nslookup.

Поиск неисправностей

См. документацию по исправлению возможных проблем

Пример реализации Kerberos SSO модуля

Диаграмма классов

Процесс авторизации:

  • Запросы на сервер universe перехватывается KerberosAuthenticationRequestInterceptor.

  • Если запрос на /login и есть header ("Single-Sign-On", true), в ответ отправляется 401 c header (""WWW-Authenticate", "Negotiate").

  • Если пришедший ответ или один из запросов присылает header ( "Authorization", "Negotiate"), KerberosServiceAuthenticationProvider:

    • Проверяет тикет;

    • Ищет пользователя в локальной БД по username с помощью KerberosUserDetailsService;

    • Устанавливает аутентификацию в контекст.

  • Запрос отправляется на endpoint /login.

  • Приложение пытается залогинить пользователя используя Authentication провайдеры из имеющихся SecurityDataSource.

  • KerberosLoginProvider проверяет контекст аутентификации.

  • В приложении создается внутренний токен для пользователя.

  • При последующих запросах авторизованного пользователя на другие endpoint'ы проверяется внутренний токен.

Тикет KDC проверяется только при запросе на endpoint /login.

Ограничения:

  1. В текущей имплементации пользователи подтягиваются из локальной БД, поэтому приложение должно быть синхронизировано с AD.

    • Пользователь не сможет залогиниться, если после его создания не была синхронизирована локальная БД приложения и AD. Error response: Пользователь не найден. Требуется синхронизация с Active Directory.

    • Если после синхронизации данные изменились, пользователь войдет в систему с устаревшими данными.

Возможные решения:

  • Синхронизировать локального пользователя с AD через LDAP Rest Template при логине.

  • Синхронизировать локального пользователя с AD используя имеющийся модуль для синхронизации через LDAP.

  • Синхронизировать локального пользователя с AD через LDAP c аутентификацией через Kerberos (LDAP search user by username with server Kerberos authentication).

  1. Если деактивировать пользователя в AD, пользователь не сможет войти в приложение, т.к. KDC не выдаст тикет. Однако, если пользователь уже авторизован в приложении автоматического логаута не произойдет.

  2. Логаут приводит к автоматической авторизации пользователя, т.к. наличие в пути /sso=true или /sso=on перенаправляет на endpoint /login.

Примеры конфигурации

krb5.conf и keytab должны быть скопированы в universe web server.

Пример конфигурации KDC:

[libdefaults]
      default_realm = USE.ME

[realms]
      USE.ME = {
               kdc = dc.use.me
      }

[domain_realm]
      use.me=USE.ME
      .use.me=USE.ME

Пример настройки в backend.properties:

security.kerberos.realm=USE.ME //edit with correct domain name
security.kerberos.keytab.file=/path/to/tomcat.keytab
security.kerberos.service.principal=HTTP/universe.use.me@USE.ME

Параметры Java:

-Djava.security.krb5.conf=/path/to/krb5.conf
-Dsun.security.krb5.debug=true //for debug only, remove when all works

Полезные команды

Команды для Windows:

  • #setspn - добавляет/проверяет связки principal name - domain name; сопоставляет внешние адреса с пользователем (Principal user HTTP/@).

    • setspn -L accountname - отображает текущий зарегистрированный SPN для учетной записи.

    • setspn -F -Q HTTP/*@* - показать созданные связки, где -F - фильтр на уровень леса (не используется, если лес из одного домена), -Q HTTP/*@* - фильтр на созданные principal name.

  • #klist

    • klist tickets - проверяет получение кешированных билетов kerberos.

    • klist get http/universe132.use.me - информация о хранимых в кэше krbTicket.

    • klist.exe -K -e -t -k c:\tomcat132.keytab - анализ файла с ключами. На основе этого ключа получаем krbTicket, продлеваемый после использования.

    • klist tgt - информация о текущем тикете из кэша учетных данных Kerberos.

    • klist purge - очищает ключи из кэша.

  • #ktpass - генерирует связку principal name - domain name - key.

    • ktpass /out c:\tomcat132.keytab /mapuser und2@UNI.ME /princ HTTP/universe132.use.me@UNI.ME /pass q1w2e3r4Q /ptype KRB5_NT_PRINCIPAL /crypto All

Команды для Linux:

  • #klist - проверяет получение кешированных билетов kerberos.

    • klist -k -t tomcat132.keytab -K -e

  • #kinit - получает тикет /etc/krb5.conf.

    • kinit girl@USE.ME

kinit для principal требует сертификат - см. официальную документацию.

Возможные ошибки

Если параметры учетной записи при настройке Windows Domain Controller with KDC не сработали корректно (Рисунок 1), и нет возможности внести исправления в домен - добавьте параметры понижения безопасности в файл krb5.conf:

[libdefaults]
clockskew = 200000
allow_weak_crypto = TRUE

В логе будет ошибка вида:

2024-02-16 11:40:24,529 [http-nio-8080-exec-1] [-] [-] WARN org.apache.cxf.phase.PhaseInterceptorChain.doLog:465 - Interceptor for {http://service.core.v2.rest.mdm.unidata.org/}LoginRestService has thrown exception, unwinding now org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
Caused by: sun.security.krb5.KrbException: Encryption type RC4 with HMAC is not supported/enabled
../../../_images/sso12.png

Рисунок 1 – Настройка параметров учетной записи