Перейти к содержанию

SAML

ℹ️ SSO (Single Sign-On) — технология единого входа, благодаря которой пользователи могут авторизоваться в нескольких приложениях с помощью одного набора учетных данных

ℹ️ Security Assertion Markup Language (SAML) — открытый стандарт передачи идентификационных данных между облачными системами. Как правило, его используют в больших организациях, где есть актуальная база пользователей, работают политики безопасности и т. п., что делает доступ к контенту в сервисе более безопасным и контролируемым

ℹ️ ADFS (Active Directory Federation Services) — компонент Windows Server, обеспечивающий функционал провайдера аутентификации для веб-приложений. ADFS расширяет возможности использования технологии единого входа, доступной в пределах одной границы безопасности или организации, в веб-приложениях. Службы ADFS тесно интегрированы с Active Directory. ADFS извлекает атрибуты пользователей из Active Directory, а также проверяет подлинность пользователей в этой системе

Настройка SP

ℹ️ Identity Provider (IDP) — поставщик удостоверений, приложение, реализующее SAML-протокол, аутентифицирующее пользователей

ℹ️ Service Provider (SP) — провайдер услуг,  приложение, предоставляющее сервис аутентифированному у Identity Provider пользователю (в нашем случае — приложение "Первая Форма")

1. Сгенерировать сертификат для подписания запросов SP ---> IDP

Сертификат представляет собой запароленный .pfx-файл, содержащий публичный и приватный ключи.

При выполнении запросов SP ---> IDP этот файл читается приложением Первой формы, и запрос подписывается этими ключами. Файл следует поместить на сервере 1F.

Публичный ключ этого сертификата (отдельный .cer-файл, сгенерированный вместе с .pfx-файлом) нужно предоставить администратору IDP, и установить его на IDP-сервере как корневой сертификат (необходимо для валидации подписи запроса).

2. Установить сертификат для валидации запросов IDP ---> SP

Сертификат (публичный ключ) можно получить у админа IDP, и установить его на 1F-сервере как корневой.

Настройка «Первой Формы»

1. Добавить сервис SAML в Провайдеры аутентификации.

2. Создать провайдер аутентификации на базе этого сервиса. Описание параметров настроек сервиса SAML вы найдете в соответствующем разделе.

3. После создания провайдера аутентификации в приложении 1F по адресу /api/auth/saml/{providerId}/metadata станут доступны метаданные-SP.

ℹ️ Метаданные — XML-файл с описанием и основными параметры конфигурации. Метаданные есть и у SP и у IDP

Этот файл следует передать администратору IDP.

В нем указаны:

  • AssertionConsumerService — эндпоинт для приема ответов аутентификации от IDP (/api/auth/saml/{providerId}/assertionconsumer)

  • SingleLogoutService — эндпоинт для приема ответов разлогина от IDP (/api/auth/saml/{providerId}/singlelogout)

Настройка appsettings.json

В файле appsettings.json в блок "Auth" необходимо добавить параметры:

"SamlEntityId": "{domain_name}",

"SamlCertificatesRoot": "{certificate.pfx_dir}"

где:

  • domain_name — доменное имя SP

  • certificate.pfx_dir — путь до директории .pfx-сертификата

Настройка приложения Linux

В каталоге приложения создать файл docker-compose.override.yml:

services:

backend:

volumes:

  • ./custom-ca-certificates:/opt/custom-ca-certificates

- ./custom-configs:/custom-configs

- ./saml/certificate.pfx:/app/saml/certificate.pfx

где:

  • custom-ca-certificates — директория, для хранения публичного сертификата для валидации запросов IDP ---> SP

  • custom-configs — директория хранения файла appsettings.json

  • /saml/certificate.pfx — путь до .pfx-сертификата

Настройка IDP

Выполняется администратором IDP. Важные шаги:

1. Получить от SP файл с метаданными-SP (/api/auth/saml/{providerId}/metadata), и создать конфигурацию

2. На сервере IDP установить сертификат (публичный ключ) из п1 "Настройка SP" как корневой.

3. Настроить отдачу необходимых claims в ответе аутентификации (в нашем случае для ADFS — primarySid)

Пример настройки для ADFS:

При использовании входа через SAML с ADFS вместе с данными аутентификации можно передавать и другие значения. Ниже описывается, как передать полное имя пользователя, организацию, номер телефона, роль или пользовательскую роль. Эти значения определяются как Claim Rules в Relying Party Trust. Чтобы отредактировать Claim Rules, выберите папку Relying Party Trusts в AD FS Management и выберите пункт Edit Claim Rule на панели действий (Actions). Новые правила добавляются нажатием кнопки Добавить правило (Add Rule) и выбором шаблона во всплывающем окне. Пример: Полное имя (Full name) Чтобы передать полное имя пользователя, создайте правило, используя шаблон Send LDAP Attributes. В поле Атрибут LDAP (LDAP Attribute) добавьте строку для фамилии (Surname) и строку для имени (Given Name). В поле Исходящий тип требования (Outgoing Claim Type) выберите Фамилия (Surname) и Имя (Given Name). Организация (Organization) Чтобы определить организацию, с которой будет ассоциирован пользователь, создайте правило, используя шаблон Send LDAP Attributes. Это правило свяжет поле в Active Directory с исходящим типом организации. Выбор атрибута LDAP зависит от того, как вы хотите распределить пользователей. Например, вы можете сопоставить разные отделы с разными организациями. В поле LDAP Attribute выберите поле, которое сопоставляется с организацией. В поле Outgoing Claim Type введите слово organization в нижнем регистре. Номер телефона (Phone number) Чтобы передать номер телефона пользователя, создайте правило, используя шаблон Send LDAP Attributes. В поле LDAP Attribute выберите Telephone-Number. В поле Outgoing Claim Type введите слово phone в нижнем регистре. Роль (Role) Назначение роли пользователю на основе его членства в группе — это процесс, состоящий из двух шагов. Сначала вы создаете новое правило, используя шаблон Send Group Membership as a Claim. Затем вы немного изменяете определение, сгенерированное этим правилом, чтобы создать пользовательское правило. Чтобы создать правило членства в группе: 1. Добавьте новое правило и выберите шаблон Send Group Membership as a Claim. 2. Найдите группу, которую вы хотите сопоставить с ролью, используя кнопку Обзор (Browse...). 3. Для Outgoing claim type выберите Role. 4. Для Outgoing claim value используйте значение end-user, agent или admin. 5. Нажмите Готово (Finish), а затем нажмите Изменить правило (Edit Rule) для только что созданного правила. 6. Используйте кнопку Просмотреть язык правил (View Rule Language), чтобы получить исходный код правила. Скопируйте этот код — он понадобится вам на следующем шаге. Чтобы создать рабочее пользовательское правило: 1. Скопировав код из окна языка правил, нажмите OK, чтобы закрыть диалоговое окно. 2. Удалите это правило и добавьте новое, используя шаблон Send Claims using a Custom Rule. 3. Вставьте скопированный код в редактор пользовательских правил, а затем удалите строку "http://schemas.microsoft.com/ws/2008/06/identity/claims/" из поля Type. Должно остаться только слово role. 4. Сохраните правило. Пользовательская роль (Custom role) Чтобы задать пользовательскую роль, вам потребуется использовать Custom Agent Roles API, чтобы получить ее идентификатор (ID). Затем выполните шаги, описанные выше для создания общего правила для роли, со следующими изменениями: 1. Вместо значения agent или admin для Outgoing claim value используйте ID роли. 2. Вместо того чтобы оставлять слово role в поле Type, измените значение на custom_role_id. Финальная инструкция в правиле будет выглядеть примерно так: issue(Type = "custom_role_id", Value = "ROLE_ID_HERE", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, ValueType = c.ValueType); Сопоставление пользовательской роли будет работать только в том случае, если у пользователя уже есть роль agent. 4. Предоставить ссылку на файл метаданных-IDP администратору SP.

В метаданных IDP описаны параметры — эндпоинты для приема запросов логина/логаута, протокол общения, публичные ключи сертификатов.

  • SingleSignOnService — эндпоинт для приема запросов аутентификации от SP

  • SingleLogoutService — эндпоинт для приема запросов разлогина от SP

Правило преобразования Name ID (обязательно для корректной работы)

В AD FS необходимо добавить правило преобразования Claim для корректной передачи Name ID в SAML-ответах.

AD FS Management → Relying Party Trusts → [RP Trust] → Edit Claim Issuance Policy → Add Rule

Тип правила: Transform an Incoming Claim

  • Incoming claim type: Windows account name
  • Outgoing claim type: Name ID
  • Outgoing name ID format: Windows Qualified Domain Name

Как работает SAML в приложении 1F

ℹ️ Вся коммуникация между SP и IDP происходит через браузер — SAML основан на HTTP-запросах и браузерных переадресациях

Логин

  • В файле app-settings.json указан настроенный SAML-провайдер со свойством:

{

"Settings": {

"LoginPath": "/api/auth/saml/{providerId}/login",

"LogoutPath": "/api/auth/saml/{providerId}/logout"

},

"ProviderType": "SAML",

"Name": "1forma.net (ADFS)",

"Id": {providerId}

}

  • SPA приложение отрисует кнопку логина через этот провайдер.

  • При клике на кнопку SPA переходит по ссылке LoginPath (/api/auth/saml/{providerId}/login),

  • 1F формирует запрос аутентификации и подписывает сертификатом, указанным в конфигурации (SignCertificatePath)

  • Запрос отправляется в браузер, и происходит переадресация на SingleSignOnService URL (указано в метаданных IDP)

  • Пользователь аутентифицируется, и IDP формирует ответ аутентификации, и перенаправляет пользователя на AssertionConsumerService (указан в метаданных SP)

  • 1F в методе /api/auth/saml/{providerId}/assertionconsumer валидирует подпись ответа, считывает claim с именем UserClaimName

  • 1F ищет пользователя с SID=claim.Value

  • 1F генерирует стандартный JWT-токен, и зашивает в него 3 дополнительных claims:

oProviderId — id провайдера аутентификации

oNameId — необходим для разлогина

oSessionIndex — необходим для разлогина на сервере IDP

  • Время жизни токена определяется параметром SecurityTokenValidTo из ответа IDP.

Выход

  • При разлогине SPA приложение считывает из токена ProviderId, и из app-settings.json LogoutPath для этого провайдера

  • SPA переходит по ссылке LogoutPath

  • 1F формирует запрос разлогина, и переадресовывает на SingleLogoutService URL (указано в метаданных IDP)

  • IDP удаляет сессию пользователя, и переадресовывает обратно на SingleLogoutService (указано в метаданных SP)

  • 1F удаляет cookie и токен

  • Пользователь разлогинен в 1F

Логирование

Вход через SAML логируется аналогично обычной аутентификации через форму: система фиксирует событие в таблице базы данных LoginsLog, сбрасывает счетчик неудачных попыток входа и автоматически добавляет IP-адрес пользователя в белый список. Выход из системы не логируется.

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

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

Сервисы

Провайдеры аутентификации