Search code examples
springspring-bootspring-securityspring-data-jpaspring-ldap

How to bypass the authentication process of Ldap while accessing in-memory database


I have developed a login page where a user can be a user from active directory(LDAP) or a local user from file based H2 database or a user from configuration file whose credentials are already stored ,For example Username - admin, Password - admin.

In the configuration file options are given to enable or disable LDAP, in-memory and H2 database authentication.

Let's assume all the 3 types of authentication are enabled and a local user from a H2 database logs-in, so according to the logic since all the 3 types of authentication are enabled a check is made in all 3 databases i.e. active directory,in-memory and H2 database if the user exists or not which should be avoided.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final Logger _LOG = LoggerFactory.getLogger(SecurityConfig.class);

private ActiveDirectoryLdapAuthenticationProvider provider;

@Autowired
private DataSource dataSource;

@Autowired
private PasswordEncoder bCryptPasswordEncoder;

@Value("${ldap.auth.enabled}")
private boolean ldapAuthEnabled;

@Value("${database.auth.enabled}")
private boolean databaseAuthEnabled;

@Value("${inMemory.auth.enabled}")
private boolean imMemAuthEnabled;

@Value("${userrole.admin.username}")
private String adminUsername;

@Value("${userrole.admin.password}")
private String adminPassword;

@Value("${ldap.domain}")
private String ldapDomain;

@Value("${ldap.url}")
private String ldapUrl;

@PostConstruct
public void configValuesForApplication() {
    _LOG.info("Ldap Authentication {}", ldapAuthEnabled);
    _LOG.info("In Memory  Authentication {} ", imMemAuthEnabled);
    _LOG.info("Ldap Authentication {}", ldapAuthEnabled);
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http
            .authorizeRequests()
            .antMatchers(
                    "/", "/reg",
                    "/js*//**//**",
                    "/css*//**//**",
                    "/img*//**//**",
                    "/webjars*//**//**").permitAll()
            .antMatchers("/user*//**//**").hasRole("USER")
            .antMatchers("/admin", "/h2_console/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/index")
            .permitAll()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
            .permitAll()
            .and()
            .exceptionHandling()
            .accessDeniedHandler(accessDeniedHandler);
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    if (imMemAuthEnabled) {
        auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER")
                .and()
                .withUser(adminUsername).password(adminPassword).roles("ADMIN");
    }
    if (databaseAuthEnabled) {
        auth.
                jdbcAuthentication()
                .authoritiesByUsernameQuery("select username, role FROM USER where username=?")
                .usersByUsernameQuery("select username,password, 1 FROM USER where username=?")
                .dataSource(dataSource)
                .passwordEncoder(bCryptPasswordEncoder);
    }
    if (ldapAuthEnabled) {
        provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        auth.authenticationProvider(provider);
    }
  }
}

login.properties file is as below

ldap.auth.enabled=true
inMemory.auth.enabled=true
database.auth.enabled=true

userrole.admin.username=admin
userrole.admin.password=admin
userrole.user.username=user
userrole.user.password=user

ldap.domain=foo.com
ldap.url=ldap://abcdef12.foo.com.:450/

spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:file:~/h2/vehicledb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

The question is how to avoid a check in LDAP and in-memory database if a user from H2 database logs-in and vice-versa?


Solution

  • You could write your own security provider

    Example is available here:

    https://www.baeldung.com/spring-security-multiple-auth-providers