Web SSO

В разделе описан механизм аутентификации через сторонних провайдеров по протоколам OpenID Connect (OIDC), включает в себя авторизацию по OAuth2.

Механизм SSO-аутентификации включается в конфигурационном файле dbaccess.properties. В параметре ru.naumen.core.authentication.authenticators необходимо добавить аутентификатор EXTERNAL (подраздел Типы аутентификаторов).

Термины и сокращения

  • ADFS — Microsoft Active Directory Federation Service.
  • IdP (identification provider, identity provider, провайдер идентификации и аутентификации) — сторонняя система, к которой SMP обращается за подтверждением аутентификации пользователей, например, ADFS, Аванпост, Keycloak и прочее.
  • idP identifier — коды параметров пользователя на сервере авторизации (idP), которые будут использоваться для идентификации пользователя.
  • OIDC — протокол OpenID Connect.
  • SP (service provider) — система, в которую происходит вход, в нашем случае это SMP.
  • SMP identifier — коды атрибутов сотрудника в SMP, которые будет использоваться для идентификации пользователя.
  • SSO (single sign-on) — принцип аутентификации, когда различные системы обеспечивают аутентификацию внутрь себя через провайдеров аутентификации. Пользователю достаточно аутентифицироваться в провайдере аутентификации, а вход во все остальные системы будет реализован через прозрачную аутентификацию. Сами SP аутентифицирующие данные, например, пароль, не хранят.
OIDC. Файл external-settings.xml

Настройка параметров протокола OIDC выполняется в файле external-settings.xml.

Параметры файла external-settings.xml

Доступные параметры:

  • clientId — идентификатор клиента в провайдере аутентификации.
  • clientSecret — секретный ключ для установления доверительных отношений между стендом SMP и сервером авторизации.

    Подлежит шифрованию, если в файле dbaccess.properties параметр encryption.enabled=true (подраздел Безопасность).

  • discoverUri — URI для чтения метаданных провайдера аутентификации.
  • gateway — URL-адрес для выхода.
  • scope — scope параметров, запрашиваемых у провайдера аутентификации. Параметры перечисляются через пробел.
  • clientAuthenticationMethod — метод аутентификации при обращении к сервису выдачи маркеров. Значение по умолчанию: client_secret_basic.
  • searchStrategy — стратегия поиска сотрудников.

    Представляет собой мапу, в которой ключом является код атрибута сотрудника в SMP, а значением код параметра пользователя в провайдере аутентификации.

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

    Доступны 4 варианта стратегии:

    • and — стратегия поиска сотрудников по совпадению всех атрибутов.

      Поиск выполняется по указанным атрибутам сотрудника в SMP и значениям, полученным от провайдера аутентификации, с условием И.

      Copy
          <and>
              <attributes>
              <entry>
                  <idpId></idpId>
                  <smpId></smpId>
              </entry>
              </attributes>
          </and>
    • or — стратегия поиска сотрудников по совпадению одного из атрибутов.

      Поиск выполняется по указанным атрибутам сотрудника в SMP и значениям, полученным от провайдера аутентификации, с условием ИЛИ.

      Copy
          <or>
              <attributes>
              <entry>
                   <idpId></idpId>
                  <smpId></smpId>
              </entry>
              </attributes>
          </or>
    • oneByOne — стратегия поиска сотрудников по порядку в зависимости от присутствия значений атрибутов сотрудника в SMP в ответе от провайдера аутентификации.

      Если значение, полученное от провайдера аутентификации, для первого из указанных атрибутов сотрудника в SMP позволяет однозначно идентифицировать только одного пользователя, то производится его аутентификация.

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

      Copy
          <oneByOne>
              <attributes>
              <entry>
                  <idpId></idpId>
                  <smpId></smpId>
              </entry>
              </attributes>
          </oneByOne>
    • script — стратегия поиска сотрудников с помощью скрипта.

      В контексте скрипта доступна мапа, содержащая:

      • коды параметров, запрошенных у провайдера;
      • значения параметров, полученных от провайдера;
      • коды атрибутов сотрудника в SMP, по которым выполняется поиск сотрудника.

      Параметр <scriptData> содержит скрипт в формате CDATA.

      Возвращаемое значение:

      • UUID объекта класса "Сотрудник" (employee), для которого необходимо выполнить аутентификацию.
      • Ошибка, если не найден ни один сотрудник или найдено больше одного.
      Copy
          <script>
              <attributes>
              <entry>
                  <idpId></idpId>
                  <smpId></smpId>
              </entry>
              </attributes>
              <scriptData></scriptData>
          </script>

Пример структуры файла external-settings.xml

Структура файла external-settings.xml является общей для аутентификации по протоколу OIDC независимо от провайдера.

Copy
<?xml version="1.0" encoding="UTF-8"?>
<ext:configuration xmlns:ext="http://www.naumen.ru/externalSettings" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.naumen.ru/externalSettings ../../../../../../../../sdng-generated/src/main/resources/xsd/externalSettings.xsd">
    <settings>
        <protocol>
            <oidc>
                <clientId>smp</clientId>
                <clientSecret>abcdefghijk</clientSecret>
                <discoverUri>https://sso.example.org/auth/realms/myrealm/.well-known/openid-configuration</discoverUri>
                <gateway>https://sso.example.org/auth/realms/myrealm/protocol/openid-connect/logout</gateway>
                <scope>openid email profile</scope>
                <clientAuthenticationMethod>client_secret_basic</clientAuthenticationMethod>
            </oidc>
        </protocol>
        <searchStrategy>
            <and>
                <attributes>
                    <entry>
                        <idpId>email</idpId>
                        <smpId>email</smpId>
                    </entry>
                    <entry>
                        <idpId>name</idpId>
                        <smpId>firstName</smpId>
                    </entry>
                    <entry>
                        <idpId>family_name</idpId>
                        <smpId>lastName</smpId>
                    </entry>
                </attributes>
            </and>
        </searchStrategy>
        <other>
            <entry>
                <key>other</key>
                <value>settings</value>
            </entry>
        </other>
    </settings>
</ext:configuration>
OIDC. Настройка взаимодействия с ADFS

Для выполнения единого входа с ADFS как поставщика необходимо включить в приложении протокол HTTPs.

Настройка со стороны провайдера ADFS

  1. Добавление группы приложений:

    • На панели управления диспетчером серверов выберите "Средства" → "Управление ADFS".

      Откроется окно ADFS.

    • В меню ADFS выберите "Группы приложений".

      Для элемента "Группы приложений" откройте контекстное меню и выберите "Добавить группу приложений".

      Откроется окно "Мастер добавления групп приложений".

    • В окне мастера (шаг "Приветствие") в поле "Имя" укажите имя приложения, в списке "Автономные приложения" выберите "Серверное приложение" и нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне мастера (шаг "Приложение сервера") скопируйте и сохраните значение поля "Идентификатор клиента" (clientId), значение будет использовано при настройке аутентификации со стороны SMP.

      В поле "Перенаправить URI" добавьте Callback URL (https://sd-address/sd/callback) и нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне мастера (шаг "Настроить учетные данные приложения") установите флажок в поле "Создать общий секрет", скопируйте и сохраните значение поля "Секрет" (clientSecret), значение будет использовано при настройке аутентификации со стороны SMP.

      Нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне мастера на шаге "Сводка" нажмите Далее.

      На шаге "Завершить" нажмите Закрыть. Группа приложений добавлена.

  2. Добавление приложения:

    • В меню ADFS выберите "Группы приложений". Откройте контекстное меню и выберите "Свойства".

      Откроется окно "Свойства".

    • В окне "Свойства" нажмите кнопку Добавить приложение.

      Откроется окно добавления нового приложения.

    • В окне добавления приложения (шаг "Приветствие") в поле "Шаблон" выберите "Веб-интерфейс API" и нажмите Далее.

      Выполнится переход на следующий шаг мастера.

    • В окне добавления приложения (шаг "Настройка веб-интерфейса") в поле "Идентификатор" добавьте значение: https://sd-address

      Нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне добавления приложения (шаг "Применение политики управления доступом") в поле "Выберите политику управления доступом" выберите "Разрешение для каждого" и нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне добавления приложения (шаг "Настроить разрешения для приложений") поле "Разрешенные области" содержит значение области (scope) по умолчанию: openid.

      Выберите дополнительные области при необходимости и нажмите Далее. Выполнится переход на следующий шаг мастера.

    • В окне добавления приложения на шаге "Сводка" нажмите Далее.

      На шаге "Завершить" нажмите Закрыть. Приложение добавлено.

    • В окне "Свойства" нажмите ОК. Настройка со стороны провайдера завершена.

Настройка со стороны SMP

  1. Создайте конфигурационный файл external-settings.xml.

    В параметрах clientId и clientSecret укажите значения, сохраненные при настройке провайдера, см. Параметры файла external-settings.xml.

  2. Перезапустите SMP для включения нового типа аутентификации.

    В дальнейшем изменения конфигурационного файла можно применять в консоли SMP командой:

    api.external.reloadConfig()

OIDC Настройка взаимодействия с Keycloak

Настройка со стороны провайдера Keycloak

  1. В консоли администратора Keycloak создайте клиента.

  2. Заполните идентификатор клиента Client ID произвольным значением.

  3. Измените настройки клиента:

    • Client Protocol — openid-connect;
    • Access Type — confidential;
    • Authorization Enabled — On;
    • Valid Redirect URIs — https://smp.example.org/sd/*;
    • Base URL — https://smp.example.org/;
    • Backchannel Logout URL — https://smp.example.org/sd/logout;
    • Backchannel Logout Revoke Offline Sessions — On.

    Если указать Backchannel Logout URL и включить Backchannel Logout Revoke Offline Sessions, то разрыв сессии в провайдере будет разрывать сессию в SMP.

  4. Сохраните изменения.

  5. Обязательно! На вкладке credentials перегенерируйте секретный ключ, нажав кнопку regenerate secret.

Настройка со стороны SMP

  1. Создайте конфигурационный файл external-settings.xml.

  2. Перезапустите SMP для включения нового типа аутентификации.

    В дальнейшем изменения конфигурационного файла можно применять в консоли SMP командой:

    api.external.reloadConfig()

Аутентификация по SSO

Работа по протоколу в рамках определенного idP

Со стороны пользователя:

  1. При переходе по URL-адресу любой страницы SMP без аутентификации (кроме прямого URL страницы входа) открывается страница для аутентификации со стороны IdP и производится запрос аутентификации пользователя в idP с перечислением параметров, которые в дальнейшем будут использоваться SMP для идентификации пользователя.
  2. При получении ответа со стороны IdP, SMP парсит его, определяет атрибуты и их значения, по которым искать сотрудника и выполняет поиск пользователя по указанным атрибутам и точному соответствию значений:

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

      В подсчете количества сотрудников не участвуют архивные сотрудники. Архивные сотрудники пропускаются при попытке аутентификации.

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

При переходе по прямому URL страницы входа (${baseurl}, ${baseurl}/index.jsp, ${baseurl}/login.jsp) аутентификация по SSO не работает.

Обработка прерывания сессии в SMP при инициации прерывания сессии со стороны IdP

SMP слушает по определенному URL запросы на прерывание сессий пользователей, приходящие со стороны IdP:

  1. Если со стороны IdP пришел запрос про прерывание сессии пользователя, то SMP:

    • Выполняет попытку разрыва сессии указанного пользователя.
    • Пишет сообщение об ошибке в лог, если определить пользователя не удалось.
  2. После разрыва сессии пользователя, происходит переход на страницу входа в систему.

    Прозрачная аутентификация через провайдеров SSO не отрабатывает.

Отправка сообщения в IdP при прерывании сессии со стороны SMP

Если прерывается сессия пользователя аутентифицированного по SSO, то:

  1. После разрыва сессии пользователя, происходит переход на страницу входа в систему.

    Прозрачная аутентификация через провайдеров SSO не отрабатывает.

  2. SMP отсылает соответствующее сообщение в IdP на указанный в настройках URL. Сообщение сигнализирует о выходе пользователя из системы.

Настройка аутентификации по SSO при переходе по прямому URL страницы входа

Чтобы аутентификация по SSO работала при переходе по прямому URL страницы входа, нужно настроить редирект с помощью конфигурации обратного прокси поверх SMP.

Пример. Если в приложении задан baseurl=https://support.naumen.ru/sd/, то чтобы аутентификация по SSO срабатывала при переходе на https://support.naumen.ru/sd/ и https://support.naumen.ru/sd нужно задать следующую конфигурацию nginx:

Copy
location ~ ^/(sd|sd/)$ {
return 301 $scheme://$host/sd/operator;
}