Как совместить два разных конфигурационных файла при загрузке Spring? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть мультипроектное приложение Spring.Проект A - отвечает за аутентификацию LDAP. Проект B - отвечает за аутентификацию базы данных. Проект MAIN - может использовать оба из них или один из них.Если мы используем только Проект A - у нас есть аутентификация LDAP. Если мы используем только Проект B - у нас есть аутентификация JDBC. Если мы используем их оба - сначала идет аутентификация LDAP, если она терпит неудачу, затем идет аутентификация JDBC.И если проект B включен, он добавляет некоторые фильтры

В Project MAIN нет файла @Configuration, но есть в проектах A и B.

Проект A @ Configuration

@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

/**адрес сервера LDAP*/
@Value("${ldap.server}")
private String ldapServer;

/**номер порта LDAP сервера*/
@Value("${ldap.port}")
private int ldapPort;

/**домен для LDAP*/
@Value("${ldap.suffix}")
private String suffix;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(adAuthProvider());
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic()
            .and()
            .authorizeRequests().antMatchers("/**").authenticated()
            .and()
            .csrf().disable();
}

/**провайдер для аутентификации через LDAP*/
@Bean
public ActiveDirectoryLdapAuthenticationProvider adAuthProvider() {

    String ldapUrl = String.format("ldap://%s:%s", ldapServer, ldapPort);

    ActiveDirectoryLdapAuthenticationProvider adAuthProvider = new 
  ActiveDirectoryLdapAuthenticationProvider(suffix, ldapUrl);
    adAuthProvider.setConvertSubErrorCodesToExceptions(true);
    adAuthProvider.setUseAuthenticationRequestCredentials(true);
    return adAuthProvider;
}

}

и файл конфигурации проекта B.

@Configuration
@EnableWebSecurity
public class ECommonConfig extends WebSecurityConfigurerAdapter {

@Autowired
private UserDetailsService userDetailsService;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(jdbcAuthProvider());    
}

@Override
protected void configure(HttpSecurity http) throws Exception {
 http.httpBasic()
            .and()
            .authorizeRequests().antMatchers("/**").authenticated()
            .and()
            .csrf().disable();
    http.addFilterAt(ldapAuthenticationFilter(), LDAPAuthenticationFilter.class);
    http.authorizeRequests().antMatchers("/**").access("@requestAuthorization.checkRequestPermissions(authentication, request)");
}

/**провайдер для аутентификации через базу данных*/
@Bean
public DaoAuthenticationProvider jdbcAuthProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}

/**бин для шифрования паролей*/
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

/**бин для фильтра проверки наличия LDAP-пользователя в базе данных*/
@Bean
public LDAPAuthenticationFilter ldapAuthenticationFilter() throws Exception {
    return new LDAPAuthenticationFilter(authenticationManager());
}

@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
    return super.authenticationManager();
}

/**бин для инициализации базы данных по умолчанию - описание параметров подключения к БД в файле application.yml*/
@Bean
public DataSource dataSource() {
    return datasourceConnectionManager().getDataSource("test");
}

/**бин создания менеджера подключения к нескольким базам данных*/
@Bean
public DatasourceConnectionManager datasourceConnectionManager() {
    return new DatasourceConnectionManager();
}
}

Мне нужно, чтобы эти две конфигурации работали вместе или только одна или их

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

Чтобы объединить эти 2 способа аутентификации, вы можете создать собственный провайдер аутентификации (подробнее здесь: https://www.baeldung.com/spring-security-authentication-provider)

Реализация провайдера аутентификации будет выглядеть примерно так:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private ActiveDirectoryLdapAuthenticationProvider ldapAuthenticationProvider;
    private DaoAuthenticationProvider daoAuthenticationProvider;

    // env variable to help you choose which auth provider should be enabled
    @Value("${ldap.enabled}")
    private int ldapEnabled;

    // env variable to help you choose which auth provider should be enabled
    @Value("${daoAuth.enabled}")
    private int daoAuthEnabled;

    @Autowired
    public CustomAuthenticationProvider(ActiveDirectoryLdapAuthenticationProvider ldapAuthenticationProvider, DaoAuthenticationProvider daoAuthenticationProvider) {
        this.ldapAuthenticationProvider = ldapAuthenticationProvider;
        this.daoAuthenticationProvider = daoAuthenticationProvider;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication);

        // if both enabled then first try with ldap, if not successful try with dao
        if (ldapEnabled && daoAuthEnabled ) {
          Authentication authenticate = ldapAuthenticationManager.authenticate(authentication);
          if(!authenticate.isAuthenticated()) {
            authenticate = ldapAuthenticationManager.authenticate(authentication);
          }
          return authenticate;
        }

        // if only ldap enabled 
        if(ldapEnabled) {
          return ldapAuthenticationManager.authenticate(authentication);
        }

        // if only dao enabled
        return daoAuthenticationProvider.authenticate(authentication);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
0 голосов
/ 06 мая 2019

Для этого вы можете использовать Spring profiling.Просто добавьте аннотацию @Profile вместе с именем в классе конфигурации, как показано ниже.Конфигурация для ProjectA

@Profile("ProjectA")
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...

И Конфигурация для ProjectB

@Profile("ProjectB")
@Configuration
@EnableWebSecurity
public class ECommonConfig extends WebSecurityConfigurerAdapter {
...

Затем во время выполнения приложения вы можете указать активный профиль, передав следующий параметр в java.

#In case of need of only ProjectA then
-Dspring.profiles.active=ProjectA
#In case of need of only ProjectB then
-Dspring.profiles.active=ProjectB
#In case of need of both projects then
-Dspring.profiles.active=ProjectA,ProjectB

То же самое вы можете определить в файле application.properties с необходимым профилем

spring.profiles.active=ProjectA,ProjectB

Таким образом, вы можете динамически решать, какую конфигурацию проекта следует включить.

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