title: Spring Security ldapAuthentication always successful
body: <p>Implementing a ldapAuthentication into my Spring Security configuration makes the process ignoring the boolean field : "enabled" on Users (org.springframework.security.core.userdetails) so it's allowing disabled Users to connect..</p>
  
  <p>The Security Config works well and it disallow disabled Users to connect with a simple authentication  using userDetailsService but it fails with ldapAuthentication.</p>
  
  <p>Here is <strong>SecurityConfig</strong> class :</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  @ComponentScan(basePackages = {"com.mykeys.test"})
  public class SecurityConfig {
  
      @Resource
      Environment environment;
      @Resource
      BaseLdapPathContextSource contextSource;
  
      private static final String PROPERTY_NAME_SECURITY_KEY = "security.key";
  
      @Resource(name="userDetailsService")
      private UserDetailsService userDetailsService;
  
      @Resource
      public void configureAuthentification(AuthenticationManagerBuilder auth) throws Exception {
          //auth.userDetailsService(userDetailsService);
          auth.ldapAuthentication()
                  .userSearchFilter("uid={0}")
                  .ldapAuthoritiesPopulator(new UserDetailsServiceLdapAuthoritiesPopulator(userDetailsService))
                  .userSearchBase(environment.getProperty(LdapConfig.PROPERTY_LDAP_USER_SEARCH_BASE, LdapConfig.DEFAULT_LDAP_USER_SEARCH_BASE) )
                  .contextSource(contextSource);
      }
  
      @Configuration
      @Order(1)
      public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
          protected void configure(HttpSecurity http) throws Exception {
  
              http
                  .antMatcher("/api/**")
                       .exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint())
  
                  .and()
                      .headers()
                          .addHeaderWriter(new StaticHeadersWriter("X-Frame-Options", "SAMEORIGIN"))
                  .and()
                      .authorizeRequests()
                          .anyRequest().authenticated();
          }
      }
  
      @Configuration
      public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
  
          @Resource
          Environment environment;
  
  
          @Override
          public void configure(WebSecurity web) throws Exception {
              web
                      .ignoring()
                      .antMatchers("/js/**", "/css/**", "/fonts/**", "/less/**", "/favicon.ico", "/holder.js/**", "/img/**", "/partial/**");
          }
  
  
  
          @Bean
          @Override
          public AuthenticationManager authenticationManagerBean() throws Exception {
              return super.authenticationManagerBean();
          }
  
  
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http
                  .formLogin()
                          .permitAll()
                          .defaultSuccessUrl("/")
                          .failureUrl("/login?error")
                  .and()
                      .logout()
                      .permitAll()
                  .and()
                      .sessionManagement()
                      .maximumSessions(1)
                          .expiredUrl("/login?error")
                      .and()
                  .and()
                     .rememberMe()
                          .key(environment.getProperty(PROPERTY_NAME_SECURITY_KEY, UUID.randomUUID().toString()))
                  .and()
                      .authorizeRequests()
                          .anyRequest()
                              .authenticated();
          }
  
      }
  }
  </code></pre>
  
  <p>Here is <strong>UserDetailsServiceImpl</strong> class (this bean is auto injected into SecurityConfig class):</p>
  
  <pre><code>@Service("userDetailsService")
  @Transactional(readOnly = true)
  public class UserDetailsServiceImpl implements UserDetailsService{
  
      private final Logger logger = LoggerFactory.getLogger(this.getClass());
  
      @Resource MessageSource messageSource;
  
      @Transactional
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          try {
  
              List&lt;GrantedAuthority&gt; list = getAllAuthor();
              org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(
                      username,
                      username,
                      false,
                      false,
                      false,
                      false,
                      list
              );
  
              return user;
  
          } catch (Exception e) {
              logger.warn("Authentification refusée pour l'utilisateur au login {}", username, e);
              throw new UsernameNotFoundException(e.getMessage());
          }
      }
  
      public static List&lt;GrantedAuthority&gt; getAllAuthor(){
          Collection&lt;String&gt; roles = new ArrayList&lt;&gt;();
          roles.add("ROLE1");
          roles.add("ROLE2");
  
          ArrayList&lt;GrantedAuthority&gt; authorities=new ArrayList&lt;GrantedAuthority&gt;();
          if (roles != null) {
              for (String roleName : roles) {
                  authorities.add(new SimpleGrantedAuthority(roleName));
              }
          }
          return authorities;
      }
  
  }
  </code></pre>
  
  <p>And here is the <strong>LdapConfig</strong> class : </p>
  
  <pre><code>    @Configuration
      @EnableLdapRepositories
      public class LdapConfig {
  
          public static final String PROPERTY_LDAP_URL = "ldap.url";
          public static final String DEFAULT_PROPERTY_LDAP_URL = "ldap://localhost:33899";
  
          public static final String PROPERTY_LDAP_LDIF_FILE  = "ldap.ldif";
          public static final String DEFAULT_LDAP_LDIF_FILE = "classpath:data/ldif/corp.mykeys.com.ldif";
  
   public static final String PROPERTY_LDAP_LOGIN_DN = "ldap.login.dn";
      public static final String DEFAULT_PROPERTY_LDAP_LOGIN_DN = "LOGIN";
  
      public static final String PROPERTY_LDAP_PASSWORD = "ldap.password";
      public static final String DEFAULT_PROPERTY_LDAP_PASSWORD = "pass";
  
          public static final String PROPERTY_LDAP_SEARCH_BASE    = "ldap.searchbase";
          public static final String DEFAULT_LDAP_SEARCH_BASE = "dc=corp,dc=mykeys,dc=com";
  
          public static final String PROPERTY_LDAP_USER_SEARCH_BASE   = "ldap.usersearchbase";
          public static final String DEFAULT_LDAP_USER_SEARCH_BASE = "OU=FR,OU=Employees";
  
          @Resource
          Environment environment;
  
          @Bean
          BaseLdapPathContextSource contextSource() throws Exception {
              LdapContextSource contextSource = new LdapContextSource();
              contextSource.setUrl(environment.getProperty(PROPERTY_LDAP_URL, DEFAULT_PROPERTY_LDAP_URL));
              contextSource.setBase(environment.getProperty(PROPERTY_LDAP_SEARCH_BASE, DEFAULT_LDAP_SEARCH_BASE));
              contextSource.setAnonymousReadOnly(true);
  
  
              contextSource.setUserDn(environment.getProperty(PROPERTY_LDAP_LOGIN_DN, DEFAULT_PROPERTY_LDAP_LOGIN_DN));
              contextSource.setPassword(environment.getProperty(PROPERTY_LDAP_PASSWORD, DEFAULT_PROPERTY_LDAP_PASSWORD));
  
              if (environment.getProperty(PROPERTY_LDAP_URL, DEFAULT_PROPERTY_LDAP_URL).contains("ldap://localhost")) {
                  ldapServer();
              }
  
              return contextSource;
          }
  
          @Bean
          LdapTemplate ldapTemplate() throws Exception { return new LdapTemplate(contextSource());
          }
  
          @Bean
          @Lazy
          public ApacheDSContainer ldapServer() throws Exception {
              ApacheDSContainer apacheDSContainer= new ApacheDSContainer(environment.getProperty(PROPERTY_LDAP_SEARCH_BASE, DEFAULT_LDAP_SEARCH_BASE), environment.getProperty(PROPERTY_LDAP_LDIF_FILE, DEFAULT_LDAP_LDIF_FILE));
              apacheDSContainer.setPort(Integer.valueOf(DEFAULT_PROPERTY_LDAP_URL.substring(DEFAULT_PROPERTY_LDAP_URL.lastIndexOf(":")+1)));
  
              return apacheDSContainer;
          }
  
          @Bean
          public String userSearchBase() {
              return environment.getProperty(PROPERTY_LDAP_USER_SEARCH_BASE, DEFAULT_LDAP_USER_SEARCH_BASE);
          }
  
      }
  </code></pre>
  
  <p>And implementing a custom userDetailsContextMapper doesn't work too..</p>