How do I implement conditional authentication in spring security based on user selection between LDAP and JDBC?

483 Views Asked by At

Hope you all are doing good and safe. I have an application which will allow a user to login either by using his LDAP credentials or using his credentials stored on database. I was able to configure separate jdbc and ldap authenticator but how can I implement it conditionally? Say, a user selects LDAP radio button on login page then it should trigger LDAP authentication and if user selects database authentication, then it should trigger jdbc authentication. Any help would be highly appreciated.

JDBC authenticator:-

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;
    
    @Override
     public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // TODO Auto-generated method stub
        
         http.authorizeRequests()
         .antMatchers("/admin").hasAnyRole("ADMIN")
         .antMatchers("/user").hasAnyRole("ADMIN", "USER")
         .antMatchers("/").permitAll()
         .and().formLogin();
    }
    
    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

**LDAP authenticator:-**

@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new AuthenticationFailureHandler() {
            String message = "";

            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                    AuthenticationException exception) throws IOException, ServletException {

                if (exception.getClass().isAssignableFrom(UsernameNotFoundException.class)) {
                    message = "User Not Found";
                } else if (exception.getClass().isAssignableFrom(DisabledException.class)) {
                    message = "Account Disabled";

                } else if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) {
                    message = "Bad Credentials";
                }
                else if (exception.getClass().isAssignableFrom(LockedException.class)) {
                    message = "Account Locked";
                }
                else {
                    message = "Internal Server Error";
                }
                response.sendRedirect("/WisoKeyinPortal/login?error=" + message);

            }  
        };
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return super.userDetailsService();
    }
 
    @Bean
    public AuthenticationProvider authProvider() {

        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();

        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());

        return authenticationProvider;

    }

    /*---------------------------For QA comment from here-------------------------------*/
    
      @Bean public AuthenticationManager authenticationManager() { return new
      ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
      }
      
      @Bean public AuthenticationProvider
      activeDirectoryLdapAuthenticationProvider() {
      ActiveDirectoryLdapAuthenticationProvider provider = new
      ActiveDirectoryLdapAuthenticationProvider("xyz.com", "ldap://xyz.com");
      provider.setConvertSubErrorCodesToExceptions(true);
      provider.setUseAuthenticationRequestCredentials(true);
      provider.setSearchFilter("sAMAccountName={1}"); return provider; }
     
    /*----------------------------For QA comment ends here-----------------------------*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        String[] staticResources = { "/css/**", "/images/**", "/fonts/**", "/scripts/**", };

        http.csrf().disable().authorizeRequests().antMatchers("/login**").permitAll().antMatchers(staticResources)
                .permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll()
                .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and()
                .logout().invalidateHttpSession(true).clearAuthentication(true)
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login").permitAll();
                //.and().sessionManagement().invalidSessionUrl("/login?error=session");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {

        //authManagerBuilder.inMemoryAuthentication().withUser("admin").password("pass").roles("ADMIN");
        
        /*---------------------------For QA comment from here-------------------------------*/
        
          authManagerBuilder.authenticationProvider(
          activeDirectoryLdapAuthenticationProvider())
          .userDetailsService(userDetailsService());
         
        /*---------------------------For QA comment from here-------------------------------*/
    }
}

0

There are 0 best solutions below