Привет, Хабр! На связи Дмитрий Грудинин. Современные корпоративные веб-приложения и облачные сервисы в обязательном порядке требуют безопасной аутентификации и авторизации пользователей. Как правило, для этого используются протоколы: SAML 2.0 или OpenID Connect (OIDC) на базе OAuth. Оба решают схожие задачи, связанные с делегированием ответственности за верификацию  пользователя стороннему доверенному провайдеру. При этом оба протокола скрывают за собой обширный арсенал различных вариантов использования, к тому же OIDC постоянно расширяется. 

Казалось бы тема IdP на основе SAML 2.0 и OIDC рассмотрена в тысячах статей, сотнях видео и прочих материалов. Зачем на эти темы что-то ещё публиковать? 

Популярность данных протоколов сыграла с ними злую шутку: информационное пространство переполнено избыточными и совершенно не нужными сведениями (теми самыми «деталями реализации»), которые мешают разработать лаконичную и правильную интеграцию по протоколам SAML 2.0 и OIDС для своих приложений. 

Любой, кто пробовал «сдружить» SAML или OIDC-приложение не из мира Microsoft с Microsoft ADFS, не понаслышке знает, сколько подводных камней скрывают особенность передачи SAML Assertions и JWT Claims как в части передачи ключей и значений атрибутов, так и в части подписи.

Но пока OIDC в сторону.  В данной статье мы рассмотрим сценарий использования протокола SAML так сказать «for dummies». Идея статьи – кратко, но ёмко и без излишеств рассказать о том, что на самом деле нужно знать в SAML. И не рассказывать о том, без чего можно прекрасно обойтись.

Сценарии использования SAML 2.0

Протокол SAML 2.0 применяется, когда нужно безопасно и удобно аутентифицировать пользователя через централизованный IdP путём делегирования задачи аутентификации тому самому централизованному IdP без передачи в явном и открытом виде учётных данных. Он особенно полезен в корпоративной среде, государственных сервисах и больших экосистемах, где требуется единый вход. Заметим, что в архитектуре SAML участвуют две стороны: поставщик услуг (Service Provider, SP) – система, куда пользователь пытается получить доступ; и поставщик удостоверений (Identity Provider, IdP) – отвечает за аутентификацию пользователя. Варианты использования SAML могут быть следующими:

1. Корпоративные системы, которые изначально поддерживают SAML 2.0

В данном случае происходит подключение уже внедренной корпоративной системы со встроенной поддержкой SAML-протокола в роли поставщика услуг (SP). В качестве примеров таких сервисов можно привести Microsoft Exchange Outlook Web Access для организации веб-доступа к корпоративной почте, Microsoft RDWeb для входа в удаленные рабочие столы Windows, VPN-системы в лице Palo Alto VPN, Cisco AnyConnect или Citrix VPN для безопасного доступа сотрудников к корпоративной сети, а также Citrix Virtual Apps and Desktops (XenApp/XenDesktop) для запуска корпоративных приложений и рабочих столов.

Как я уже отметил выше, эти системы изначально поддерживают SAML, поэтому он используется в качестве механизма единого входа, даже несмотря на появление более современных протоколов вроде OpenID Connect. К тому же такой подход более логичный в историческом аспекте: стоит заметить, что перечисленные приложения были разработаны еще до появления OpenID Connect, поэтому компании предпочитают использовать встроенные возможности вместо сложных доработок. К тому же SAML проще в настройке чем OIDC: в частности, если OpenID Connect требует дополнительных API-запросов, то SAML работает на уровне перенаправлений браузера и передачи XML-токенов. Об этом мы чуть подробнее поговорим далее по тексту. 

2. Облачные сервисы (SaaS), в которых SAML 2.0 позволяет связать корпоративную инфраструктуру с веб-приложениями

В отличие от корпоративных решений, облачные сервисы работают через интернет и предоставляют доступ множеству организаций. Хорошим примером здесь станут такие сервисы как «Яндекс 360», CRM «Битрикс24» и консоль управления облачными ресурсами Yandex Cloud. SAML в данном случае используется для того, чтобы связать внутреннюю корпоративную аутентификацию с этими сервисами. 

Применение SAML в подобных сценариях вполне обосновано тем, что в отличие от OAuth/OIDC, где SP должен делать API-запросы к поставщику удостоверений (IdP), в SAML все взаимодействие идет через браузер пользователя с использованием HTTP-редиректов. А это в свою очередь избавляет облачный сервис от необходимости подключаться к внутренним системам компании. Также отмечу, что облачные сервисы могут работать с разными IdP, и, если в компании уже развернут ADFS, Keycloak, OpenAM или другой IdP, их можно использовать без модификации SaaS-сервиса. 

Ключевые отличия SAML 2.0 от OpenID Connect (OIDC)

SAML 2.0 и OpenID Connect предназначены для организации единого входа и управления аутентификацией пользователей, но у них разные архитектурные подходы, механизмы работы и области применения. SAML использует XML-формат и сложные цифровые подписи, передавая данные через браузер (HTTP Redirect / POST) и применяется в корпоративных системах, в то время как OIDC – это RESTful-протокол, который использует JWT и API-запросы, что делает его более удобным для веб-приложений, «облаков» и мобильных сервисов. 

Кроме того, SAML 2.0 работает на основе SAML Request / SAML Response, передаваемых через браузер пользователя, что устраняет необходимость прямой сетевой связи между SP и IdP. Это упрощает интеграцию и позволяет SP не иметь доступа к внутренним системам IdP. OIDC же использует фреймворк OAuth 2.0 в качестве базового механизма и передает JWT-токены через API-запросы, требуя сетевого взаимодействия с IdP. Эта особенность и является ключевым драйвером распространения SAML 2.0 в среде SaaS-сервисов, которым требуется интеграция с on-premise инфраструктурой компаний.

Характеристики

SAML 2.0

OpenID Connect (OIDC)

Основа протокола

XML (может использовать SOAP)

JSON + REST API

Формат токенов

XML (SAML Assertion)

JWT (JSON Web Token)

Транспортный механизм

HTTP-редиректы и POST-запросы через браузер пользователя

HTTP-запросы через API (бэкенд-взаимодействие между SP и IdP), редиректы

Обмен данными

SAML Request (аналог параметров редиректа OIDC) / SAML Response (аналог ID Token, Access Token, но взаимодействие через браузер, без прямой связи SPIdP)

ID Token, Access Token (через прямое API-взаимодействие)

Недостатки SAML 2.0 в сравнении с OIDC

XML-фреймворк SAML, появившийся в начале 2000-х годов, можно по праву назвать архаичным в сравнении с OIDC. SAML 2.0 разработан для веб-приложений и не поддерживает нативные мобильные приложения. При этом он решает только задачи аутентификации, не предоставляя механизмов авторизации, а SOAP и XML-канонизация делают отладку более сложной, чем в случае с OIDC, который использует REST API и JSON-токены и проще настраивается (не требуя при этом глубоких знаний XML, сертификатов и подписей). Также наличие в OIDC штатного набора scopes и claims существенно сужает пространство ошибок при интеграции приложений. В SAML же весь маппинг атрибутов между IdP и SP нужно выполнять «ручками». При этом далеко не каждый SP примет «общепринятный» атрибут, который будет работать в десятке других SP. Это ощутимо усложняет настройку и пуско-наладочные работы.

Как итог: SAML не подходит для интеграции в современные мобильные сервисы ввиду своей негибкости и отсутствия масштабируемости. А вот применение данного протокола в корпоративных системах (VPN, VDI, к примеру, Citrix Virtual Apps and Desktops или Microsoft RDWeb, почта, к примеру, Exchange EWS/OWA/ECP и т.д.) по-прежнему актуально из-за исторической совместимости и простоты интеграции. И, как мы уже отметили выше, в облачных сервисах («Яндекс 360», «Битрикс24», Yandex Cloud) SAML также удобен, потому что не требует прямого взаимодействия между SP и IdP – все передается через браузер.

Схема работы протокола SAML 2.0 на примере абстрактного Service Provider  

На представленной схеме изображен процесс аутентификации пользователя с использованием SAML. В основе работы лежит передача SAML-запроса (SAML Request) от поставщика услуг к поставщику удостоверений и возврат SAML-ответа (SAML Response) после успешной аутентификации пользователя.

Аутентификация заключается в подтверждении личности пользователя. Сервер авторизации может реализовать это двумя основными способами: 

  • самостоятельно выполнить верификацию, например спросив и проверив пароль, OTP-код по алгоритму TOTP, отправив пуш-запрос в мобильное приложение-аутентификатор или выполнив электронную подпись на отчуждаемом ключевом носителе, к примеру, Рутокен ЭЦП.

  • делегировать задачу аутентификации внешнему источнику (например, отправив пользователя в какой-нибудь государственный Identity Provider, к примеру, ЕСИА от Минцифры или общедоступный коммерческий типа VK ID или Yandex ID), попросив его подтвердить личность пользователя и вернуть результат. Когда внешний источник выполняет собственную проверку личности пользователя, мы говорим о внешнем поставщике удостоверений (IdP). После завершения аутентификации внешний IdP возвращает подписанный SAML Assertions-документ, и сервер авторизации проверяет его. Затем внешний IdP выдает клиенту такой же SAML Assertion-документ, содержащий необходимые клиенту атрибуты пользователя. При этом атрибуты могут быть как переданы “по цепочке” из одного SAML Assertion-документа во второй, но могут быть добавлены самим IdP, с которым взаимодействует приложение.

1. Ключевые компоненты схемы:

  • Identity Provider (Avanpost FAM) – поставщик удостоверений, который проверяет личность пользователя.

  • Key+Cert – означает, что Avanpost FAM использует криптографическую подпись для защиты SAML-коммуникации и может использовать сертификат TLS для шифрования соединений при передаче данных между IdP и SP.

  • /.well-known/samlidp.xml – метаданные IdP (Avanpost FAM) в формате SAML Metadata XML. В этом файле могут содержаться URL’ы точек входа (например, куда отправлять SAML Request), описание поддерживаемых методов шифрования и подписей, открытые ключи IdP (Avanpost FAM) для проверки подписей, а также конфигурации протоколов и форматов аутентификации.

  • WebApp Service Provider (SP) – приложение, предоставляющее сервис пользователю, но делегирующее аутентификацию IdP (Avanpost FAM). SP может загружать samlidp.xml для автоматической настройки взаимодействия с IdP (Avanpost FAM).

  • ACS (Assertion Consumer Service) – компонент на стороне SP, который обрабатывает SAML-ответ.

  • Аутентифицированный пользователь (Actor) – конечный пользователь, который запрашивает доступ к веб-приложению (WebApp).

  • Связь через HTTP Redirect и HTTP POST – механизм передачи SAML-запросов и ответов.

2. Этапы аутентификации:

  • Шаг 1: Пользователь пытается получить доступ к веб-приложению поставщика услуг.

  • Шаг 2: Приложение перенаправляет пользователя на IdP (Avanpost FAM) с SAML-запросом через HTTP Redirect.

  • Шаг 2: Пользователь проходит аутентификацию в IdP (Avanpost FAM): например, вводит логин и пароль).

  • Шаг 3: После успешной аутентификации IdP (Avanpost FAM) отправляет SAML-ответ в SP через HTTP POST.

  • Шаг 4: SP проверяет SAML-ответ (например, цифровую подпись и срок ее действия) и предоставляет пользователю доступ.

Как работает протокол SAML 2.0

С пояснением компонентов и этапов закончили, а теперь давайте разберем как работает протокол SAML 2.0 на представленной нами схеме. 

Шаг 1: Запрос аутентификации

Как мы видим, сначала происходит инициирование аутентификации: пользователь (Actor) открывает страницу для входа в веб-приложение поставщика услуг, нажимает на кнопку авторизации, после чего SAML и поставщик удостоверений подключаются для аутентификации. WebApp перенаправляет клиента на IdP с помощью SAML Request через HTTP Redirect. SAML Request – это XML-запрос на аутентификацию, который сервис отправляет IdP, чтобы инициировать вход пользователя. Выглядеть этот запрос может так:

<samlp:AuthnRequest
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  ID="_abc123xyz" /* уникальный идентификатор запроса */
  Version="2.0"
  IssueInstant="2025-03-07T10:03:00Z" /* время отправки запроса (SAML Timestamp) */
  Destination="https://idp.example.com/sso" /* URL IdP, куда направляется запрос */
  ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
  AssertionConsumerServiceURL="https://sp.example.com/acs"> /* конечная точка ACS, куда IdP отправит SAML Response */
  
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> /* кто отправил запрос (SP) */
      https://sp.example.com
  </saml:Issuer>

  <samlp:NameIDPolicy
      Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
      AllowCreate="true"/>
  
  <samlp:RequestedAuthnContext /* запрашиваемый контекст аутентификации (например, с указанием, что необходимо проверить как минимум пароль) */
      Comparison="exact">
      <saml:AuthnContextClassRef>
        urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
      </saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

При использовании HTTP Redirect Binding, SAML Request сжимается, кодируется в Base64 + URL Encoding и передается на IdP как параметр запроса такого плана:

В данном случае SAMLRequest=fVJdT8IwFP4r… – закодированный SAML-запрос, а остальная часть ссылки – URL, куда пользователь вернется после успешной аутентификации. 

Стоит учитывать, что де-факто весь мир SAML-приложений давно отказался от использования HTTP Redirect Binding в пользу HTTP Post Binding. Причина - ограниченная длина и невозможность передачи по сетевой инфраструктуре больших массивов атрибутов. При этом нельзя забывать, что в корпоративной инфраструктуре по-прежнему живы “мамонты” с HTTP Redirect Binding без поддержки режима Post Binding.

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

Как видно из примера выше, запрос аутентификации создается с настроенным Issuer Entity ID в качестве SAML EntityID в сообщении. При этом по умолчанию запрос SAML AuthnRequest не подписывается, когда он отправляется. Однако, когда настроено хранилище для подписания запросов, оно используется для добавления цифровой подписи в сообщение AuthnRequest. Если необходимо запросить конкретный формат NameID, это можно настроить в параметре request-options/nameid-format аутентификатора SAML. Настроенное значение будет включено в элемент NameIDPolicy/Format в сообщении SAML AuthnRequest.

Опасность параметра NameID и NameID Policy в том, что как разные IdP, так и разные SP, совершенно по-разному интерпретируют смысл значений атрибутов. Кто-то игнорирует, кто-то воспринимает как обязательное требование, кто-то - как рекомендацию, но ведёт себя на своё усмотрение. Этот нюанс зачастую создаёт сложные проблемы, поскольку NameID де-факто единственный определённый в спецификации ключевой атрибут для SAML Assertion-документа.

Шаг 2: Аутентификация у провайдера удостоверений

После редиректа на страницу Avanpost FAM и ввода, к примеру, логина/пароля,  для верификации запроса в приложение IdP проверяет кто отправил запрос (Issuer), и информацию о конечной точке ACS (AssertionConsumerServiceURL), куда нужно будет отправить ответ через SAML Response. Имейте в виду, что в SAML Response поддерживается только одна Assertion с одним ключом. Если IdP возвращает несколько Assertions, сообщение принимается, но используется только первая Assertion. Остальные Assertions полностью игнорируются. 

Шаг 3: «Ответ» / передача аутентификационных данных

На этом этапе IdP формирует SAML Response, который включает Assertion, и отправляет его через HTTP POST в ACS на стороне SP. SAML Assertion – это специальный XML-документ, который используется в протоколе SAML 2.0 для передачи информации о пользователе от провайдера удостоверений к сервису. Говоря иначе, набор SAML Assertions является «цифровым паспортом», который сервис (в нашем случае приложение поставщика услуг) использует, чтобы убедиться в том, что человек действительно аутентифицирован. «Ответ» может выглядеть так:

<samlp:Response>
    <saml:Assertion> /* объект утверждения */
        <saml:Issuer>https://idp.example.com</saml:Issuer> /* кто выдал утверждение (IdP) */
        <saml:Subject> /* идентификация пользователя */
            <saml:NameID>user@example.com</saml:NameID>
        </saml:Subject>
        <saml:Conditions NotBefore="2025-03-01T10:03:00Z" NotOnOrAfter="2025-03-01T10:18:00Z"/> /* срок действия сессии */
        <saml:AuthnStatement AuthnInstant="2025-03-01T10:03:00Z"/> /* информация о входе */
        <saml:AttributeStatement> /* атрибуты пользователя */
            <saml:Attribute Name="email">
                <saml:AttributeValue>user@example.com</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
        <ds:Signature>...</ds:Signature> /* цифровая подпись, подтверждающая подлинность утверждения */
    </saml:Assertion>
</samlp:Response>

Получив его, приложение проверяет достоверность цифровой подписи, истечение ее срока действия и ключевой идентификатор пользователя (NameID). Заметим, что все SAML Assertion подписываются приватным ключом IdP, к примеру, Avanpost FAM, а проверяются с помощью публичного ключа, который известен приложению на стороне SP

Публичный ключ приложение может получать либо из SAML Discovery-документа (того самого .well-known/samlidp.xml), но практика показывает что из-за нелюбви в мире SAML-приложений к прямому взаимодействию между SP и IdP прямой запрос даже Discovery-документа сложности с открытием прямого сетевого соединения между SP и IdP. Поэтому чаще всего на практике параметры доверия типа сертификата сервера и ACS на стороне SP указываются вручную.

Здесь сразу стоит упомянуть, что у SAML Assertion существуют три варианта защиты, которые обеспечивают разный уровень безопасности: 

  • Без подписи и шифрования (не рекомендуется)

    В данном случае SAML Assertion передает данные без подписи и без шифрования и SP может без проблем прочитать их.

    Нет гарантии, что Assertion не был изменен третьими лицами.

    Любой, кто перехватит такой Assertion, сможет использовать его (в частности, для кибератак «повторного воспроизведения» или replay attack).

  • С подписью (гарантия целостности и аутентичности)

    Тут в SAML Assertion добавляется цифровая подпись, которая подтверждает, что данные были отправлены именно этим IdP и не были изменены. Как следствие: SP может проверить подлинность IdP, убедившись, что подпись совпадает.

    Гарантия целостности: никто не сможет изменить Assertion после его создания.

    Передаваемые данные остаются в открытом виде, то есть не защищены от просмотра третьими лицами.

  • С шифрованием (защита конфиденциальности данных)

    ✅ В этом варианте Assertion сначала подписывается, а затем зашифровывается с использованием сертификата SP, а значит – данные остаются конфиденциальными. Более того: даже если кто-то перехватит Assertion, он не сможет его прочитать. Дешифровать информацию сможет только SP, так как владеет закрытым ключом.

    ❌ Подпись (если она добавлена перед шифрованием) все еще может быть проверена после расшифровки.

    SP должен уметь расшифровывать Assertion (не все библиотеки это поддерживают).

SAML Assertion

Целостность данных

Конфиденциальность данных

Необходимо наличие подписи

Необходима расшифровка

Без подписи и шифрования (небезопасный)

С подписью (минимальный уровень безопасности)

С шифрованием (высший уровень безопасности)

Шаг 4: Предоставление доступа

Если проверка SAML Response, содержащего Assertion, выполнена успешно, – ACS передает информацию WebApp, после чего приложение предоставляет пользователю доступ к сервису. Но… Чтобы правильно обработать входящий SAML Response от IdP и принять решение о предоставлении доступа, необходимо выполнить несколько ключевых проверок:

  • Подпись SAML Response и SAML Assertions, корректность сертификата

    Проверить, что SAML Response и Assertion подписаны доверенным IdP; убедиться, что сертификат, использованный IdP, соответствует тому, который указан в метаданных (samlidp.xml), и что SAML Response валидный (XML соответствует SAML-спецификации). Также рекомендуется следить за сроком действия самого сертификата сервера и тем, что он не находится в списках отзыва, но на практике данная мера применяется достаточно редко.

  • Срок действия SAML Assertion 

    Метка времени saml:Timestamp (в SAML Response и Assertion) должна быть актуальной. Срок действия Assertion проверяется по полям NotBefore / NotOnOrAfter – она должна быть валидна на момент проверки. В нашем примере срок действия составляет 15 минут после выпуска SAML Assertion. Если NotOnOrAfter истекает, Assertion считается недействительной и отклоняется.

  • Соответствие AudienceRestriction и Destination

    А еще необходимо убедиться, что в Assertion указан корректный SP (то есть, приложение, которое принимает аутентификацию) и проверить, что SAML Response предназначен именно для текущего ACS.

Как сопоставить пользователя по SAML Response?

Напомним, что параметр NameID в Assertion содержит уникальный идентификатор пользователя. Этот ID может быть email’ом, логином, UUID или другим значением, в зависимости от настроек IdP. Также SAML Response может содержать дополнительные атрибуты в элементе AttributeStatement: (например, email, username, group, role), которые можно использовать как для авторизации, так и для управления правами доступа. Такой подход может быть полезен, если SP использует RBAC (role-based access control). В этом случае атрибуты group или role из SAML Response могут использоваться для автоматического назначения ролей пользователю при входе.

Можно ли создать пользователя на основе SAML Response?

Да…, если политика сервис-провайдера позволяет это сделать. В таком случае, если пользователь уже есть в системе, просто обновляем атрибуты. Если пользователя нет, можно создать его автоматически на основе SAML Response: например, присвоить ему уникальный идентификатор NameID и AttributeStatement (email, username, group, role). Однако стоит принимать во внимание, что автоматическое создание пользователей может быть нежелательным, если IdP управляется сторонней не особенно доверенной организацией. В данном случае следует сверяться со своими внутренними списками субъектов перед созданием пользователя.

Сколько времени можно доверять SAML Response?

Стандартное время жизни ответа определяется параметрами NotOnOrAfter в Assertion. Лучшим вариантом будет доверять SAML Response в пределах заданного времени действия (обычно 5-15 минут). Также можно использовать одноразовые токены (One-Time Use), чтобы предотвратить их повторное использование, и включать проверку Replay Attack (например, хранить уже использованные токены в кэше и отклонять повторные).

Интеграция существующего приложения с IdP по протоколу SAML

Интеграция веб-приложений с поставщиками удостоверений (IdP) по протоколу SAML 2.0 позволяет реализовать единую точку аутентификации пользователей. Допустим, что у нас есть IdP (в нашем примере – многофакторная система корпоративной аутентификации с поддержкой двусторонних механизмов федерации Avanpost FAM), доступный по HTTPS, приложение с поддержкой SAML 2.0, имеющее ACS (Assertion Consumer Service) для приема аутентификационных данных, и пользователи, которые будут проходить аутентификацию через IdP для доступа к приложению.

1. Настраиваем интеграцию на стороне приложения

Для успешного обмена сообщениями между аутентификатором SAML 2.0 в роли поставщика услуг (SP) и удаленной системой в роли поставщика удостоверений (IdP) требуется базовая настройка. Также существует ряд необязательных параметров, позволяющих настроить поведение аутентификатора. 

Шаг 1: Определение параметров приложения

Чтобы приложение, поддерживающее SAML 2.0, корректно работало с IdP должно быть настроено с указанием как минимум следующих параметров:

  • ACS (Assertion Consumer Service URL) – URL, куда IdP должен отправлять SAML Response после успешной аутентификации.

  • Issuer (Entity ID) – уникальный идентификатор приложения в системе SAML.

Эти параметры обычно задаются в конфигурации. Например, в приложении с поддержкой SAML конфигурация может выглядеть следующим образом:

<EntityDescriptor entityID="https://app.example.com/saml">
	<SPSSODescriptor protocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
  	<AssertionConsumerService
    	Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    	Location="https://app.example.com/saml/acs"
    	index="0"/>
	</SPSSODescriptor>
</EntityDescriptor>

Для проверки цифровых подписей в полученных от IdP сообщениях Response или Assertion параметр signature-verification-key должен указывать на хранилище ключей (keystore), содержащее сертификат подписи IdP. В большинстве случаев эта настройка будет включать указание на сертификат X509 в keystore (данный сертификат используется для аутентификации, шифрования и подписи данных в различных протоколах, включая SAML 2.0).

<KeyDescriptor use="signing"> /* указание, что ключ используется для проверки подписи */
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
<X509Data> 
<X509Certificate> 
MIIBIjANBgkqh... (сертификат IdP) /* публичный сертификат IdP (в формате Base64), который используется для проверки подписи в ответах и утверждениях, полученных от IdP */
</X509Certificate> 
</X509Data> 
</KeyInfo> 
</KeyDescriptor>

Таким образом, когда SP получит SAML Response или Assertion от IdP, он использует сертификат в KeyDescriptor для проверки подписи сообщения. Если подпись валидна и сообщение не изменено, то данные от IdP считаются доверенными и могут быть обработаны.

По умолчанию сообщение Response от IdP должно содержать подписанную Assertion. Также возможно потребовать подпись всего сообщения Response. Эти требования могут настраиваться независимо друг от друга. Один и тот же сертификат используется как для проверки подписи Response, так и для проверки подписи Assertion. Так, параметр wantsAssertionsSigned требует подпись Assertion, а параметр wantsResponsesSigned – требует, что очевидно, подпись Response. При этом IdP должен быть настроен так, чтобы подписывать Assertion и/или Response в соответствии с требованиями SP. Для этого в параметр <SPSSODescriptor> необходимо добавить следующие атрибуты:

AuthnRequestsSigned="true" 
WantAssertionsSigned="true" 
WantResponsesSigned="true"

Шаг 2: Задание параметров IdP

На этом этапе у нас есть два варианта:

  1. Использовать адрес Discovery-документа IdP (если есть прямая связь между приложением и Avanpost FAM). Например: https://fam/.well-known/samlidp.xml. Этот документ содержит метаданные IdP, включая сертификаты, URL для аутентификации и другие параметры.

  2. Вытащить параметры вручную из файла samlidp.xml (если автоматическое обнаружение недоступно). В файле samlidp.xml содержатся следующие параметры:

    • SingleSignOnService URL – точка входа для аутентификации пользователей;

    • SingleLogoutService URL – точка выхода из системы;

    • X.509 сертификат – используется для проверки подписи ответов IdP.

Пример фрагмента samlidp.xml:

<EntityDescriptor entityID="https://fam.idp"> /* в метаданных IdP ссылается на идентификатор удаленного SAML IdP */
	<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
  	<KeyDescriptor use="signing"> /*содержит сертификат X509, который поставщик услуг использует для проверки подписанного ответа SAML IdP */
    	<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
      	<X509Data>
        	<X509Certificate>MIIBIjANBgkqh...</X509Certificate>
      	</X509Data>
    	</KeyInfo>
  	</KeyDescriptor>
  	<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    	Location="https://fam.idp/sso"/> /* место, куда следует перенаправить пользователя для аутентификации */
	</IDPSSODescriptor>
</EntityDescriptor>

После получения этих данных они вносятся в настройки приложения.

Для безопасной работы аутентификатор SAML должен быть настроен на подпись запросов аутентификации, а SAML IdP должен подписывать ответы аутентификации. Тем не менее можно временно отключить подпись в целях устранения неполадок, установив параметры wants-assertion-signed (указывает, должен ли SP требовать подписанных утверждений от IdP) и wants-response-signed (определяет, ожидает ли SP, что весь SAML Response будет подписан IdP) на false и отключив request-signing-key (задает закрытый ключ для подписи SAML-запросов SP. Если отключен, запросы не подписываются). Эти параметры задаются в конфигурации библиотеки или модуля SAML, который используется в приложении. В зависимости от используемой платформы эти параметры могут устанавливаться в конфигурационном файле или в коде. После отладки не забудьте вернуть настройки подписей обратно.

2. Настраиваем IdP (на примере Avanpost FAM)

Теперь на стороне IdP (Avanpost FAM) необходимо настроить параметры приложения (SP): добавить Entity ID и ACS URL приложения в список доверенных сервисов, указать политики аутентификации (например: использовать LDAP, OTP, сертификаты) и настроить атрибуты, которые будут передаваться в SAML Response (email, role, group и т.п.).

Вкладка настройки атрибутов
Вкладка настройки атрибутов
Настройка сценария MFA
Настройка сценария MFA

3. Отладка процесса аутентификации

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

? Основные этапы аутентификации, которые необходимо проверить

  1. SAML Request: Приложение (SP) отправляет SAML Request на SingleSignOnService IdP. Запрос передается через HTTP Redirect или HTTP POST.

  2. Аутентификация пользователя — IdP проверяет пользователя и создает ответ с подтверждением аутентификации.

  3. SAML Response: IdP отправляет подписанный SAML Response обратно в приложение (SP) через HTTP POST на ACS URL. В ответе содержатся атрибуты пользователя.

? Пример анализа с помощью отладчика в браузере

Для отладки можно использовать встроенные инструменты браузера, такие как DevTools в Google Chrome или Firefox. Они позволяют отслеживать и анализировать запросы и ответы, связанные с SAML, включая SAML Request и SAML Response.

  1. Откройте DevTools в браузере (нажмите F12 или используйте комбинацию клавиш Ctrl+Shift+I).

  2. Перейдите на вкладку Network. Вкладка Network в DevTools будет отображать запросы типа POST на URL, как, например, /sso. Отслеживайте запросы на этот URL, и в деталях запроса посмотрите тело сообщения. В нем должен быть SAML Request, закодированный в формате Base64.

  3. Фильтруйте запросы по ключевому слову saml, чтобы отслеживать только соответствующие запросы и ответы.

  4. Запустите процесс аутентификации (например, выполните вход в приложение).

  5. В списке запросов выберите запрос SAML Request и SAML Response для их анализа.

? Как анализировать запросы

  • SAML Request: Это запрос, который приложение отправляет в IdP. Он будет зашифрован и закодирован, а не в читаемом виде. В DevTools можно увидеть, что этот запрос будет передаваться через метод HTTP Redirect или HTTP POST. Например, если это POST-запрос, проверьте, что параметры запроса содержат строку, похожую на <SAMLRequest>.

  • SAML Response: Ответ IdP на запрос аутентификации. Он будет содержать атрибуты пользователя, а также подпись для проверки подлинности. Внимательно проверяйте параметры ответа. Ошибки могут возникать, если в ответе отсутствуют необходимые атрибуты или если подпись не совпадает с ожидаемой.

? Пример анализа с помощью режима отладки в Avanpost FAM/MFA+

Включаем режим отладки для приложения
Включаем режим отладки для приложения

Впрочем, для диагностики процесса аутентификации в Avanpost FAM/MFA+ гораздо удобнее и проще будет использовать встроенный режим отладки приложения. Он позволяет собирать и анализировать данные о работе SP, в том числе видеть запросы и ответы, связанные с SAML.

  1. Включите режим отладки для нужного приложения в профиле приложения (раздел  «Управление приложениями»).

  2. Перейдите во вкладку  «Журнал отладки», где фиксируются записи о попытках аутентификации.

  3. Запустите процесс аутентификации: например, выполните вход в интегрированное приложение.

  4. Откройте журнал отладки и найдите соответствующие записи, где можно просмотреть детали передаваемых сообщений SAML Request и SAML Response.

  5. Проанализируйте логи для выявления возможных ошибок, несоответствий или проблем в конфигурации.

Этот способ позволяет детально изучать процесс взаимодействия сервисов без необходимости использования сторонних инструментов.

3.1. Декодирование SAML-сообщений

SAML-запросы и ответы обычно передаются в виде строк Base64-encoded. Для того чтобы разобраться, что именно передается, нужно декодировать эти строки: только тогда мы сможем понять, какие параметры содержатся в запросах и ответах, и проверить их на наличие ошибок. Существует несколько онлайн-инструментов и расширений для браузеров, которые могут помочь нам в дешифровке.

  1. Для начала скопируйте закодированную строку из запроса или ответа.

  2. Теперь перейдите на сайт декодера SAML, например, SAMLtool или Base64 Decode.

  3. Вставьте строку в соответствующее поле и получите расшифрованное содержимое.

3.2. Проверка ошибок в ответах

При анализе SAML Response важно следить за несколькими типичными ошибками:

  • Ошибка подписи: Если ответ от IdP подписан некорректно, приложение не сможет его проверить. Это может происходить, если на стороне IdP используются неверные или устаревшие сертификаты.

  • Отсутствие атрибутов: Убедитесь, что все необходимые атрибуты (email, role, group и т.п.) присутствуют в ответе. Если атрибуты отсутствуют или имеют неверные значения, это может привести к проблемам с авторизацией пользователя.

  • Неверный формат данных: Если IdP отправляет данные в неверном формате (например, неверно закодированное значение), приложение может не распознать эти данные.

3.3. Логирование и дополнительные инструменты

Для более глубокой диагностики следует использовать логи на стороне приложения и IdP. Важно, чтобы логи содержали информацию о запросах и ответах SAML.

  • Логи приложения: убедитесь, что в них есть информация о полученных SAML Response и возможных ошибках при их обработке.

  • Логи IdP: обязательно проверьте их, чтобы убедиться, что запросы обрабатываются корректно и IdP возвращает правильные ответы.

Журнал событий безопасности FAM
Журнал событий безопасности FAM
Пример лога на сервере FAM
Пример лога на сервере FAM

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

3.4. Наиболее частые ошибки при интеграции SAML 2.0

  • Неверные или устаревшие сертификаты: Проверка подписей в SAML-ответах может не пройти, если сертификат на стороне IdP не актуален. Диагностируется не всегда легко и очевидно, но на практике это первое, что следует проверить. Возможно у вас просто истёк сертификат IdP, а конкретный SP это проверяет.

  • Неверные URL: Убедитесь, что все URL (например, для SingleSignOnService и ACS) прописаны корректно и соответствуют настройкам IdP.

  • Проблемы с атрибутами: IdP может не передавать нужные атрибуты, либо их формат может быть неверным. Это самая сложно отлавливаемая проблема, особенно если в качестве IdP используется какой-нибудь Microsoft ADFS, скудный на логи. При этом в Avanpost FAM данная проблема диагностируется ощутимо проще за счёт интерфейса отладки интеграции, который позволяет сдампить содержимое всех SAML Request и SAML Response.

Отладка процесса SAML-аутентификации требует внимательного анализа запросов и ответов, с использованием инструментов вроде DevTools и SAML декодеров. Важно следить за корректностью настроек – как на стороне приложения, так и на стороне IdP. Инструменты для логирования, декодирования и анализа сетевого трафика помогают выявить и исправить возможные ошибки.

Заключение

Несмотря на появление более современных протоколов, SAML 2.0 остается актуальным решением для реализации единого входа в корпоративной среде. Судьба данного протокола очень похожа на судьбу таких протоколов как RADIUS, и даже как Modbus – сколько бы их ни пытались «отправить на пенсию» – они живее всех живых, и на них работает огромное число инфраструктурных компонентов и систем в большинстве компаний.

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

При этом недостатки кроются в его достоинствах – крайне сложная реализация механизмов полноценного Single Logout в задачах SSO, подход «работает – не трогай» для ранее настроенных интеграций – все боятся, что что-нибудь «отвалится», ну и в целом заковыристость процесса первичной настройки при попытке «сдружить» по SAML новые системы. 

Современные поставщики удостоверений, такие как Avanpost FAM, поддерживают не только сами протоколы SAML и OIDC, но и стараются предоставить набор отладочных инструментов и возможность гибкой параметризации SAML Assertions, что упрощает задачу для администраторов по настройке, вводу систем в эксплуатацию и решению проблем. При этом все аспекты безопасности и поведения аутентификации могут централизованно управляться через настройки на стороне IdP – без необходимости вносить изменения в каждое приложение отдельно. Это делает SAML 2.0 компромиссным выбором в условиях сложной корпоративной инфраструктуры и сохраняет за ним почётное место в ИТ-ландшафте большинства компаний.

Комментарии (2)


  1. methlab
    05.06.2025 13:32

    Еще стоит порекомендовать полезные тулзы от OneLogin: https://developers.onelogin.com/saml/online-tools/x509-certs/obtain-self-signed-certs
    Помогают сильно сократить время отладки поддержки SAML в приложении и в принципе лучше понять технологию.