title: Spring Security multiple UserDetailsService
body: <p>I have 3 different tables and every table has user-information. (Maybe the same username but different passwords)</p>
  
  <p>Also, have 3 different URLs for authorization. Is it possible to use multiple <code>UserDetailsService</code> with one configuration and during authorization control which table to use?</p>
  
  <p>Here is my configuration code but I can't control which table to use during authorization:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
  @Import(SecurityProblemSupport.class)
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      private final AuthenticationManagerBuilder authenticationManagerBuilder;
  
      @Qualifier("userDetailsService")
      private final UserDetailsService userDetailsService;
  
      @Qualifier("customerDetailsService")
      private final UserDetailsService customerDetailsService;
  
      private final TokenProvider tokenProvider;
  
      private final CorsFilter corsFilter;
  
      private final SecurityProblemSupport problemSupport;
  
      public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, UserDetailsService customerDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
          this.authenticationManagerBuilder = authenticationManagerBuilder;
          this.userDetailsService = userDetailsService;
          this.customerDetailsService = customerDetailsService;
          this.tokenProvider = tokenProvider;
          this.corsFilter = corsFilter;
          this.problemSupport = problemSupport;
      }
  
      @PostConstruct
      public void init() {
          try {
              authenticationManagerBuilder
                  .userDetailsService(userDetailsService)
                  .passwordEncoder(passwordEncoder())
                  .and()
                  .userDetailsService(customerDetailsService)
                  .passwordEncoder(passwordEncoder());
          } catch (Exception e) {
              throw new BeanInitializationException("Security configuration failed", e);
          }
      }
  
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Override
      public void configure(WebSecurity web) throws Exception {
          web.ignoring()
              .antMatchers(HttpMethod.OPTIONS, "/**")
              .antMatchers("/app/**/*.{js,html}")
              .antMatchers("/i18n/**")
              .antMatchers("/content/**")
              .antMatchers("/swagger-ui/index.html")
              .antMatchers("/test/**");
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
              .exceptionHandling()
              .authenticationEntryPoint(problemSupport)
              .accessDeniedHandler(problemSupport)
              .and()
              .csrf()
              .disable()
              .headers()
              .frameOptions()
              .disable()
              .and()
              .sessionManagement()
              .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              .and()
              .authorizeRequests()
              .antMatchers("/api/register").permitAll()
              .antMatchers("/api/activate").permitAll()
              .antMatchers("/api/authenticate").permitAll()
              .antMatchers("/api/account/reset-password/init").permitAll()
              .antMatchers("/api/account/reset-password/finish").permitAll()
              .antMatchers("/api/**").authenticated()
              .antMatchers("/management/health").permitAll()
              .antMatchers("/management/info").permitAll()
              .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
              .antMatchers("/v2/api-docs/**").permitAll()
              .antMatchers("/swagger-resources/configuration/ui").permitAll()
              .antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
              .and()
              .apply(securityConfigurerAdapter());
  
      }
  
      private JWTConfigurer securityConfigurerAdapter() {
          return new JWTConfigurer(tokenProvider);
      }
  }
  </code></pre>
  
  <p><strong>userDetailsService</strong> and <strong>customerDetailsService</strong> are my <code>UserDetailsService</code> implementations that use different tables for check credential. But I can't control exactly which UserDetailsService to use when a request came.</p>