SAMLException: InResponseToField ответа не соответствует отправленному сообщению
Мы работаем над приложением, которое защищено с помощью Spring Security Saml.
Аутентификация работает нормально, но есть одна проблема со следующим рабочим процессом в производственной среде.
- пользователь запрашивает незащищенный адрес www.server.com
- ответом является html-страница со встроенным скриптом, который заменяет window.location.href на защищенную saml-страницу (поставщик услуг) www.server.com/app/action?param1=value1¶m2=value2
- Spring Saml определяет необходимость аутентификации и перенаправляет пользователя в форму входа (поставщик удостоверений) на www.login-server.com
- на этом этапе форма входа в систему является первой страницей, которая отображается пользователю
- пользователь добавляет эту страницу входа в качестве закладки (включая связанные с saml параметры URL для этого сеанса http) www.login-server.com/adfs/ls/?SAMLRequest=xxx&SigAlg=xxx&Signature=arGdsZwJtHzTDjQP1oYqbjNO
- пользователь работает с приложением...
- на следующий день пользователь открывает эту закладку и авторизуется
- IdP перенаправляет к SP, но принадлежащий сеанс http уже истек
Теперь мы получаем следующее исключение в нашем приложении:
org.opensaml.common.SAMLException: InResponseToField ответа не соответствует отправленному сообщению arGdsZwJtHzTDjQP1oYqbjNO
Любые идеи, как обрабатывать этот рабочий процесс, чтобы пользователь мог использовать приложение после успешного входа в систему? Спасибо за ваши ответы!
2 ответа
Мы решили нашу проблему со следующими изменениями в конфигурации Spring Saml:
- В бобе с идентификатором
successRedirectHandler
(org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
) мы устанавливаем defaultTargetUrl для init-Action нашего приложения (включая все параметры запроса). Этот URL будет автоматически использоваться в случае SSO, инициированного IdP. - В бобах с идентификатором
contextProvider
(org.springframework.security.saml.context.SAMLContextProviderLB
) мы устанавливаем для StorageFactory значениеorg.springframework.security.saml.storage.EmptyStorageFactory
, Это отключает проверку InResponseToField.
Когда вы создаете запрос AuthnRequest, у запроса есть идентификатор, который ваше приложение каким-то образом хранит. Соответствующий ответ от IdP должен иметь атрибут InResponseTo, установленный на то же значение идентификатора, чтобы ваше приложение могло проверить, что ответ предназначен для отправленного им запроса.
Однако, когда ваш пользователь добавил в закладки ссылку adfs, содержащую запрос (www.login-server.com/adfs/ls/?SAMLRequest=xxx...), ваше приложение полностью забыло об этом запросе. Другими словами, он больше не хранил идентификатор запроса и не мог проверить ответ.
Решение состоит в том, чтобы запретить пользователям добавлять в закладки ссылку www.login-server.com/adfs/ls/?SAMLRequest=xxx.... Вместо этого они должны пометить ссылку в вашем приложении, где оно может сгенерировать новый запрос и отправить его в ADFS.