1. Установите направление и область
Сначала нарисуйте конкретную связь словами: внешний IdP отправляет ответ в Keycloak, действующий как SP/broker, либо Keycloak выдаёт ответ приложению-SP. Этот материал разбирает первую связь по исходникам 26.8.1. Укажите realm, alias провайдера, клиента при наличии, binding и точный узел наблюдения. Другой SAML-клиент или направление нельзя объявлять проверенным этим примером. Зафиксируйте установленный релиз; тег исходников и изменяемая документация latest не являются доказательством версии работающего сервера. Согласуйте UTC-интервал и доступные копии данных.
2. Найдите тип события и точную ветвь
В рассматриваемом SAMLEndpoint сервер отдельно проверяет форму документа, destination, подпись и условия assertion. Несколько отказов возвращают invalid_saml_response; при неподходящем destination эта ветка добавляет details.reason=invalid_destination. Нельзя заключать «истёк сертификат» или «неверные часы» только по generic error. Сохраняйте соседнее server message и причину, если они доступны. EventBuilder преобразует тип в *_ERROR; для этой ветви получается IDENTITY_PROVIDER_RESPONSE_ERROR. Возможное отсутствие установленного clientId/userId не заполняется данными другой попытки.
3. Проверьте сохранение до вывода об отсутствии
В EventType 26.8.1 у IDENTITY_PROVIDER_RESPONSE_ERROR saveByDefault=false. Поэтому включённый event store с настройками по умолчанию не гарантирует наличие этого типа: нужны сведения о выбранных типах именно в исследуемый период. Listener/server log и сохранённый event store обрабатываются раздельно. Уточните экспорт, страницы и период хранения. Эта инструкция читает уже полученные копии; включение событий сейчас не восстановит прошлые отказы. Пустую API-выдачу отделяйте от запрета доступа и ошибки разбора формата.
4. Разберите пример без лишнего вывода
В синтетическом событии error=invalid_saml_response уточнён reason=invalid_destination. Это подтверждает зарегистрированное расхождение назначения в выбранной ветви, но ничего не сообщает о результате всех следующих проверок. Отдельный авторский лист оставляет подпись, audience, временные условия и replay неизвестными. Первое jq-выражение сохраняет общий контекст отказа, второе отбирает только имеющуюся причину destination. Оба читают JSON-массив EventRepresentation. Текстовый server log и HTTP POST с SAMLResponse не являются таким массивом и требуют собственного безопасного разбора у владельца данных. Приведённые jq-фильтры сами не ограничивают время: используйте массив, заранее выгруженный за нужное UTC-окно, либо добавьте явное условие по time, учитывая миллисекунды Unix-времени. Не смешивайте записи разных периодов только из-за одинаковых realm и клиента.
5. Сверьте независимые ограничения SAML
Сравните фактическое назначение с ожидаемым endpoint и доверенными metadata; Destination и Recipient не заменяют Audience. По результатам штатного валидатора отдельно проверьте подписи и используемые ключи, audience, correlation InResponseTo и временные границы. Для Web Browser SSO bearer profile учитывает Recipient/NotOnOrAfter, привязку к запросу и replay-защиту POST. Само время Keycloak event не заменяет условий assertion или часов участников. Допуск времени фиксируется по действующей конфигурации, а не увеличивается как способ «починить» отказ. Сертификат подписи SAML не тождественен сертификату HTTPS.
6. Найдите причину изменения и последствия
Если расходятся endpoint или ключ, запросите историю согласованной настройки metadata, hostname/proxy и ротации у владельцев обеих сторон. Административный аудит Keycloak поможет проверить изменение ресурса, когда оно действительно сохранялось; текущий снимок не доказывает историческое значение. Успех аутентификации у внешнего IdP ещё не доказывает принятия ответа Keycloak и входа в приложение. Сопоставьте доступные идентификаторы, временные границы и результат приложения, сохраняя разрывы. Не воспроизводите сохранённую SAMLResponse и не отправляйте assertion в онлайн-декодер.
7. Если остался только общий отказ
Перечислите конкретно отсутствующие свидетельства: ветвь обработчика, reason, результат подписи, metadata на момент попытки, время участников или журнал приложения. Не выдавайте invalid_signature за самостоятельное доказательство атаки; не выдавайте отсутствие сообщения replay за доказательство отсутствия повторной доставки. Для дальнейшей проверки передайте владельцу обезличенный контекст, не cookies, assertion или приватные ключи. Не отключайте TLS, проверку подписей, destination/audience или защиту от повторного использования. Итог может достоверно фиксировать только этап отказа и необходимые следующие данные.