Как декодировать SAML-сообщение
- Вставьте то, что у вас есть. Подойдёт любой из вариантов:
- само значение
SAMLResponseилиSAMLRequest, URL-кодированное или нет SAMLRequest=…сRelayState,SigAlgиSignatureили без них- весь Redirect-URL, скопированный из адресной строки
- HTML-форма с автоотправкой и скрытым полем
SAMLResponse - сырой XML
- само значение
- Декодер сам определит привязку: обычный Base64 означает HTTP-POST, а данные, сжатые deflate, означают HTTP-Redirect.
- Сначала прочитайте сводку, затем отформатированный XML под ней. XML показывается как текст и никогда не рендерится.
Направление Кодировать работает в обратную сторону: вставьте AuthnRequest и получите значение для Redirect, параметр SAMLRequest= или полный URL, собранный по атрибуту Destination. Это удобно, чтобы повторить запрос при тестировании поставщика услуг.
Привязка Redirect и привязка POST
| HTTP-Redirect | HTTP-POST | |
|---|---|---|
| Транспорт | Строка запроса GET | Скрытое поле формы с автоотправкой |
| Кодирование | raw DEFLATE, затем Base64, затем URL-кодирование | Только Base64 |
| Типичное сообщение | AuthnRequest, LogoutRequest | Response с утверждениями |
| Подпись | Отдельные параметры SigAlg и Signature | XML-подпись внутри сообщения |
| Как узнать | нет постоянного префикса, после Base64 получаются двоичные данные | PHNhbWxwOl (<samlp:), PHNhbWwycDp (<saml2p:), PD94bWwg (<?xml ) |
Redirect использует сжатие, потому что у URL есть практические ограничения длины. В примере на этой странице AuthnRequest из 464 символов сжимается до 273 байт и передаётся как 364 символа Base64. Ответы несут подписи и сертификаты, поэтому слишком велики для URL и идут через POST. Декодер принимает и данные в обёртке zlib, которые некоторые поставщики услуг отправляют в Redirect вместо raw deflate.
Что проверить, когда SSO не работает
Сводка вытаскивает поля, из-за которых чаще всего ломается вход:
- Status: всё, кроме
urn:oasis:names:tc:SAML:2.0:status:Success. Подкод вродеAuthnFailed,InvalidNameIDPolicyилиRequestDeniedназывает причину, аStatusMessageчасто добавляет подробности. - Destination и ACS URL: должны в точности совпадать с конечной точкой, настроенной у поставщика услуг, включая
httpsи завершающий слеш. - Audience: должна совпадать с entity ID поставщика услуг. Здесь часто ошибаются в конфигурации после переименования приложения.
- Conditions:
NotBeforeиNotOnOrAfterсверяются с вашими часами. «Срок условий истёк…» или «Условия ещё не действуют» при свежем входе указывают на расхождение часов между IdP и SP. - InResponseTo: должен совпадать с
IDзапросаAuthnRequest. Несовпадение говорит об устаревшем или повторно отправленном ответе. При входе, инициированном IdP, атрибута нет, и некоторые поставщики услуг такой ответ отклоняют. - NameID и Format: идентификатор, по которому SP ищет пользователя, например
emailAddressилиpersistent. - Атрибуты: каждый атрибут со всеми значениями. По ним видно, отправляет ли IdP группы или email, которые ожидает SP.
Декодирование SAML в Python
import base64, zlib
from urllib.parse import unquote
def decode_post(value):
return base64.b64decode(value).decode()
def decode_redirect(value):
raw = base64.b64decode(unquote(value))
return zlib.decompress(raw, -15).decode()
-15 говорит zlib, что на входе raw deflate без заголовка. Вызывайте unquote только для значений, скопированных из URL: значение из POST-формы уже записано обычным Base64, и URL-декодирование может превратить + в пробел. Подробнее в статье Base64 в Python, а про сжатие рассказывает страница о raw deflate и zlib.
Конфиденциальность SAML-утверждений
Утверждение содержит имена, адреса электронной почты, членство в группах, а иногда и другие персональные данные, а действующее утверждение, пока не истёк его срок, может сработать как токен входа. Эта страница декодирует его локально и не может никуда отправить. И всё же перед тем как вставлять утверждения в тикеты или чаты, вычищайте из них данные, а перехваченный ответ считайте сессионной cookie, пока не наступит его NotOnOrAfter.
Вопросы и ответы
Как перехватить SAML-ответ в браузере?
Откройте инструменты разработчика, на вкладке Network включите Preserve log и войдите в систему. Найдите POST-запрос на ACS URL поставщика услуг и скопируйте поле формы SAMLResponse из его payload. Вставьте его сюда.
Почему мой SAMLRequest не декодируется обычным декодером Base64?
В привязке HTTP-Redirect XML перед Base64 и URL-кодированием сжимается raw deflate. Обычный декодер покажет двоичный мусор. Этот инструмент делает URL-декодирование, декодирование Base64 и распаковку за один шаг.
Проверяет ли декодер подпись SAML?
Нет. Он показывает, подписаны ли сообщение, утверждение или строка запроса, но не сверяет подпись с сертификатом IdP. Подпись проверяет поставщик услуг.
Может ли он расшифровать EncryptedAssertion?
Нет. Для зашифрованных утверждений нужен закрытый ключ поставщика услуг. Декодер считает их и всё равно показывает незашифрованный конверт: статус, издателя и адресата.