Я добавляю Spring SAML в некоторые программы, которые до сих пор использовали только OAuth2. Мне нужно убедиться, что OAuth по-прежнему работает, поскольку SAML доступен только для некоторых наших клиентов.
Я столкнулся с проблемой, когда старый oAuth, кажется, больше не работает (хотя SAML в основном в порядке). Кажется, что диспетчер аутентификации как-то перезаписывается, но непонятно, как и почему. Вот соответствующий код в моем WebSecurityConfig.java:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordService.getEncoder())
.and()
.authenticationProvider(samlAuthenticationProvider)
.authenticationProvider(oAuth2AuthenticationProvider());
}
И SAMLConfig.java:
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Collections.singletonList(samlAuthenticationProvider()));
}
Очевидно, что это неправильно, но как исправить непонятно.
Когда я отлаживаю, AuthenticationManagerBuilder.performBuild () вызывается три раза при запуске.
При входе в систему дважды вызывается ProviderManager.authenticate ().
Почему? Как мне исправить это, чтобы я мог либо направить учетные данные в SAML в некоторых случаях и OAuth во всех других случаях, либо разрешить любым учетным данным, которые не работают в SAML, переполняться в OAuth?
@ M.Deinum Хорошо. Не могли бы вы уточнить? Я следую нескольким примерам, которые это делают.
См. github.com/vdenotaris/spring-boot-security-saml-sample/blob/…. Ваш SAMLConfig
также должен расширять WebSecurityCOnfiger
или, что еще лучше, вы хотите поместить его в один WebSecurityConfig
, чтобы вы могли получить общий authenticationManager
.
@ M.Deinum Хорошо. Что делает такой подход правильным? Часть моего вопроса включала «почему», поскольку я предпочитаю понимать, а не слепо следовать. Может, это ответ?
Почему это мой первый комментарий. Вы предоставляете свой собственный глобальный менеджер аутентификации, который содержит только поставщика аутентификации SAML, что в основном делает ваш configure
из AuthenticationManagerBuilder
бесполезным.
@ M.Deinum А, понятно. Почему бы не опубликовать более полный ответ, а не фрагментарный в комментариях?
@AlbeyAmakiir Я пытаюсь добиться подобного. У вас есть ссылка на git, где я мог бы сослаться на то, чего вы достигли, и как вы это решили.
new ProviderManager()
создает AuthenticationManager, который пропускает процесс компоновки, поэтому он не отображается при отладке performBuild()
.
Метод bean-компонента authenticationManager()
предназначен для возврата существующего глобального AuthenticationManager, но способ его использования в вопросе вместо этого возвращает новый и другой AuthenticationManager, перезаписывая то, что возвращает построитель. Вот почему делает отображается при отладке authenticate()
, а встроенный AuthenticationManager - нет.
Решение состоит в том, чтобы передать существующий AuthenticationManager на SAMLProcessingFilter.setAuthenticationManager()
, а не новый. Я сделал это следующим образом: переместил весь код из SAMLConfig.java в WebSecurityConfig.java, что было проще, но это не единственный способ сделать это.
Столкнулся с очень похожей проблемой. Можете поделиться конфигурацией?
Вы регистрируете глобальный
AuthenticationManager
с помощью методаauthenticationManager
. Вы не должны этого делать.