Как сделать подключаемую аутентификацию в Spring Boot JavaConfig? - PullRequest
0 голосов
/ 23 января 2020

Я мигрирую модернизирую веб-приложение monolithi c в микропроектах Spring Boot.

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

В основном у меня есть:

  • Войдите в систему как "root" с паролем, зашифрованным в конфигурации ( и да, пароль по умолчанию, как известно, «root»)
  • Имя пользователя и пароль по сравнению с хэшами, хранящимися в базе данных
  • Active Directory
  • Generi c LDAP
  • Заголовки Preauth SSO (т.е. SiteMinder и совместимый)
  • OAuth2 через Office 365
  • X509
  • SAML 2.0
  • Несколько по спецификации клиента c плагины, каждый из которых имеет свой собственный профиль

Каждый плагин имеет свой собственный XML файл конфигурации, защищенный соответствующим профилем.

Теперь я сделал следующее:

@Order(90) //Lowest, so it is the first
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http//

            .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer
                //<sec:xss-protection/>
                .xssProtection(xXssConfig -> xXssConfig.block(true))
             .... and so on

            .formLogin(formLogin -> .....)
    }


    //Generic configuration of the AuthenticationManagerBuilder
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.eraseCredentials(true);
        super.configure(auth);
    }

}

@Order(101)
@Profile(SpringProfiles.ROOT_USER)
@Configuration
public class RootUserSecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        log.warn("Initializing authentication for security profile {}", getBeanName());
        auth.authenticationProvider(rootAuthenticationProvider());
    }

}

@Order(102)
@Profile(SpringProfiles.DATABASEUSER)
@Configuration
public class DbUserSecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        log.warn("Initializing authentication for security profile {}", getBeanName());
        auth.authenticationProvider(dbAuthenticationProvider());
    }

}

Мотивация : Я хочу разработать ( move ) некоторые плагины, особенно те, которые приносят много JAR (например, SAML) в различные проекты Gradle, чтобы включить их только в построить в соответствии с требованиями установки. Вот почему я не помещаю все в один класс @Configuration. Spring Auto Scan сделает все остальное, определив доступные классы конфигурации.

Моя проблема в том, что теперь, когда я пытаюсь войти в систему, используя имя пользователя и пароль, я получаю следующую ошибку

org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:227) ~[spring-security-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:95) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)

Это Насколько я понимаю, UsernamePasswordAuthenticationFilter не связан ни с одним провайдером, где он должен быть связан с ProviderManager, предоставляющим двух провайдеров, одного для root и одного для пользователя базы данных.

Обратите внимание, что пока Я разрабатываю по частям, я выбрал портированную только системную учетную запись и вход в базу данных и оставляю дополнительные плагины на следующие дни кодирования.

Вопрос : почему при использовании дополнительных классов WebSecurityConfigurationAdapter неправильно регистрируется добавленный AuthenticationProvider s в контекст?


Изменения

Что я тоже пробовал:

  • После этого вопроса Я пытался сменить свои плагины на @Autowired методов, вводящих AuthenticationManagerBuilder, но безуспешно

1 Ответ

0 голосов
/ 24 января 2020

Решением было расширение с GlobalAuthenticationConfigurerAdapter вместо WebSecurityConfigurerAdapter.

Это потому, что WebSecurityConfigurerAdapter является «глобальной» конфигурацией, которая генерирует фильтр безопасности. Внутри он генерирует объект configurer для AuthenticationManager, который равен AuthenticationManagerBuilder.

. Чтобы этот экземпляр передавал через компоненты профилей, Spring ищет дополнительные компоненты, реализующие SecurityConfigurer<AuthenticationManager, AuthenticationManagerBuilder>, из которых GlobalAuthenticationConfigurerAdapter является удобным абстрактным классом.

Этот подход должен использоваться только для провайдеров аутентификации, подключенных к аутентификации по имени пользователя / паролю.

Плагины SSO, для которых требуется дополнительный фильтр , должен быть объявлен по-другому. Я буду работать над ними в следующие дни.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...