title: Configure Spring security for Ldap connection
body: <p>I have to configure Spring security to authenticate user through LDAP.
  This is the subtree where manager user is: </p>
  
  <pre><code>ldaps://vldp.floal:636/CN=Administration,CN=fdam,DC=fg,DC=local
  </code></pre>
  
  <p>and this is where users are:</p>
  
  <pre><code>ldaps://vldp.floal:636/CN=ProxyUsers,CN=fdam,DC=fg,DC=local
  </code></pre>
  
  <p>So I use this setting:</p>
  
  <pre><code>@Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
       auth.ldapAuthentication()
        .contextSource()
          .url("ldaps://vldp.floal:636/DC=fg,DC=local")
          .managerDn("CN=A0XXX32,CN=Administration,CN=fdam,DC=fg,DC=local")
          .managerPassword(password)
        .and()         
        .userSearchBase("CN=ProxyUsers,CN=fdam")     
        .userSearchFilter("(CN={0})")
        .ldapAuthoritiesPopulator(myAuthPopulator);     
  }
  </code></pre>
  
  <p>The problem is exception thrown when I try to make login through user, i receive this error:</p>
  
  <pre><code>2016-03-25 14:43:14 [http-nio-8086-exec-6] ERROR o.s.s.w.a.UsernamePasswordAuthenticationFilter - An internal error occurred while trying to authenticate the user.
  org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031522C9, problem 2001 (NO_OBJECT), data 0, best match of:
      'CN=fdam,DC=fg,DC=local'
   ]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031522C9, problem 2001 (NO_OBJECT), data 0, best match of:
      'CN=fdam,DC=fg,DC=local'
   ]; remaining name 'cn=F67XXX7A,cn=ProxyUsers,cn=fdam'
      at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:207) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:82) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:167) ~[spring-security-core-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192) ~[spring-security-core-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:93) ~[spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:120) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) [spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) [spring-web-4.2.1.RELEASE.jar:4.2.1.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.26]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.26]
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [catalina.jar:8.0.26]
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.26]
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:8.0.26]
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [catalina.jar:8.0.26]
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.26]
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:8.0.26]
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.26]
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [catalina.jar:8.0.26]
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-coyote.jar:8.0.26]
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-coyote.jar:8.0.26]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526) [tomcat-coyote.jar:8.0.26]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482) [tomcat-coyote.jar:8.0.26]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.26]
      at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
  Caused by: org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031522C9, problem 2001 (NO_OBJECT), data 0, best match of:
      'CN=fdam,DC=fg,DC=local'
   ]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031522C9, problem 2001 (NO_OBJECT), data 0, best match of:
      'CN=fdam,DC=fg,DC=local'
   ]; remaining name 'cn=F67XXX7A,cn=ProxyUsers,cn=fdam'
      at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:183) ~[spring-ldap-core-2.0.2.RELEASE.jar:2.0.2.RELEASE]
      at org.springframework.security.ldap.authentication.BindAuthenticator.bindWithDn(BindAuthenticator.java:148) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.ldap.authentication.BindAuthenticator.authenticate(BindAuthenticator.java:95) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      at org.springframework.security.ldap.authentication.LdapAuthenticationProvider.doAuthentication(LdapAuthenticationProvider.java:189) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      ... 41 common frames omitted
  Caused by: javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031522C9, problem 2001 (NO_OBJECT), data 0, best match of:
      'CN=fdam,DC=fg,DC=local'
   ]
      at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3160) ~[na:1.8.0_60]
      at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3081) ~[na:1.8.0_60]
      at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2888) ~[na:1.8.0_60]
      at com.sun.jndi.ldap.LdapCtx.c_getAttributes(LdapCtx.java:1329) ~[na:1.8.0_60]
      at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getAttributes(ComponentDirContext.java:235) ~[na:1.8.0_60]
      at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getAttributes(PartialCompositeDirContext.java:141) ~[na:1.8.0_60]
      at javax.naming.directory.InitialDirContext.getAttributes(InitialDirContext.java:152) ~[na:1.8.0_60]
      at org.springframework.security.ldap.authentication.BindAuthenticator.bindWithDn(BindAuthenticator.java:124) ~[spring-security-ldap-4.0.2.RELEASE.jar:4.0.2.RELEASE]
      ... 43 common frames omitted
  </code></pre>
  
  <p>There is a problem with spring parameters because if I use java code to authenticate users it works.
  I can't figure out where is the problem, can you help me?</p>
  
  <p>I went in debug and this is the output before the error:</p>
  
  <pre><code>2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.security.web.FilterChainProxy - /login at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
  2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
  2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Request is to process authentication
  2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
  2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.s.l.a.LdapAuthenticationProvider - Processing authentication request for user: F67XXX7A
  2016-03-30 11:35:22 [http-nio-8086-exec-6] DEBUG o.s.s.l.s.FilterBasedLdapUserSearch - Searching for user 'F67XXX7A', with user search [ searchFilter: '(CN={0})', searchBase: 'CN=fdam', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldaps://vldp.floal:636/dc=fg,dc=local'
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.s.l.SpringSecurityLdapTemplate - Searching for entry under DN 'dc=fg,dc=local', base = 'cn=fdam', filter = '(CN={0})'
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.s.l.SpringSecurityLdapTemplate - Found DN: CN=F67XX7A,CN=ProxyUsers,CN=fdam
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.s.l.a.BindAuthenticator - Attempting to bind as cn=F67XX7A,cn=ProxyUsers,cn=fdam,dc=fg,dc=local
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.s.l.DefaultSpringSecurityContextSource - Removing pooling flag for user cn=F67XX7A,cn=ProxyUsers,cn=fdam,dc=fg,dc=local
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldaps://vldp.floal:636/dc=fg,dc=local'
  2016-03-30 11:35:23 [http-nio-8086-exec-6] DEBUG o.s.s.l.a.BindAuthenticator - Retrieving attributes...
  2016-03-30 11:35:23 [http-nio-8086-exec-6] ERROR o.s.s.w.a.UsernamePasswordAuthenticationFilter - An internal error occurred while trying to authenticate the user.
  </code></pre>
  
  <p>PS: If with a ldap browser use <code>CN=F67XXX7A,CN=ProxyUsers,CN=fdam,DC=fg,DC=local</code> it binds.</p>
  
  <p><strong>UPDATE</strong>: if I use java without Spring login works, I need to use Spring and figure out how to configure it:</p>
  
  <pre><code>@Override
  public void isAuthenticated(String username, String password) throws LdapException{
      if (databaseMatlabClientServices.getByUsersEnabled(username)== null)
          throw new LdapException("User doesn't exist into DART database. Please contact the administrator!");
      String dn="";;
      //First query to retriev DN
      Hashtable&lt;String, Object&gt; ldapEnv = new Hashtable&lt;String, Object&gt;();
      ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      ldapEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
  //Without authentication        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "none");
      //With authentication to access to LDAP server
      ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
      ldapEnv.put(Context.SECURITY_PRINCIPAL, env.getRequiredProperty(PROPERTY_NAME_LDAP_NAME));
      ldapEnv.put(Context.SECURITY_CREDENTIALS, env.getRequiredProperty(PROPERTY_NAME_LDAP_PASSWORD));
      String[] returnAttribute = {"dn"};
      DirContext ctx = null;
      NamingEnumeration&lt;SearchResult&gt; results = null;
      try {
          ctx = new InitialDirContext(ldapEnv);
          SearchControls controls = new SearchControls();
          controls.setReturningAttributes(returnAttribute);
          controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  // without authentication on local server String filter = "uid=" + username ;
          String filter = "CN=" + username ;
          results = ctx.search(env.getRequiredProperty(PROPERTY_NAME_LDAP_USERSEARCHBASE), filter, controls);
          if (results.hasMore())
              dn = results.nextElement().getNameInNamespace();
          else 
              throw new LdapException("Wrong username. Please retry!");
      } catch (NamingException e) {
          throw new LdapException(e);
      } finally {
          try{
              if (results != null)
                  results.close();             
              if (ctx != null) 
                  ctx.close();
          }catch(Exception e){
              throw new LdapException(e);
          }
      }
  
      //Second query to try to access with obtained Dn and given password
      Hashtable&lt;String, Object&gt; authEnv = new Hashtable&lt;String, Object&gt;();
      authEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
      authEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
      authEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
      authEnv.put(Context.SECURITY_PRINCIPAL, dn);
      authEnv.put(Context.SECURITY_CREDENTIALS, password);
      DirContext ctx2 = null;
      try {
          ctx2 = new InitialDirContext(authEnv);
      } catch (AuthenticationException authEx) {
          throw new LdapException("Authentication error. Password was wrong");
      } catch(Exception e){
          throw new LdapException(e);
      }finally {
          try{         
              if (ctx2 != null) 
                  ctx2.close();
          }catch(Exception e){
              throw new LdapException(e);
          }
      }
  }
  </code></pre>
  
  <p><strong><em>UPDATE @pczeus code</em></strong>:
  To set referral=follow I have used this code:</p>
  
  <pre><code>DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldaps://vldp.floal:636/");
  contextSource.setUserDn("CN=A0XXX32,CN=Administration,CN=fdam,DC=fg,DC=local");
  contextSource.setPassword(password);
  contextSource.setReferral("follow"); 
  contextSource.afterPropertiesSet();
  
  LdapAuthenticationProviderConfigurer&lt;AuthenticationManagerBuilder&gt; ldapAuthenticationProviderConfigurer = auth.ldapAuthentication();
  
  ldapAuthenticationProviderConfigurer
      .ldapAuthoritiesPopulator(myAuthPopulator)
      .userSearchFilter("(CN={0},CN=ProxyUsers,CN=fdam,DC=fg,DC=local)")
      .userSearchBase("")
      .contextSource(contextSource);
  </code></pre>
  
  <p>and I receive the classic exception:</p>
  
  <pre><code>2016-04-07 09:34:41 [http-nio-8086-exec-4] ERROR o.s.s.w.a.UsernamePasswordAuthenticationFilter - An internal error occurred while trying to authenticate the user.
  org.springframework.security.authentication.InternalAuthenticationServiceException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001E5, problem 2001 (NO_OBJECT), data 0, best match of:
      ''
   ]; nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001E5, problem 2001 (NO_OBJECT), data 0, best match of:
      ''
   ]; remaining name '/'
  </code></pre>
  
  <p>if I add <code>.userSearchBase("CN=ProxyUsers,CN=fgadam,DC=fg,DC=local")</code>
  I receive </p>
  
  <pre><code>2016-04-07 10:32:56 [http-nio-8086-exec-4] DEBUG o.s.s.l.s.FilterBasedLdapUserSearch - Searching for user 'F6XXX7A', with user search [ searchFilter: '(CN={0},CN=ProxyUsers,CN=fdam,DC=fg,DC=local)', searchBase: 'CN=ProxyUsers,CN=fdam,DC=fg,DC=local', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
  2016-04-07 10:32:57 [http-nio-8086-exec-4] DEBUG o.s.l.c.s.AbstractContextSource - Got Ldap context on server 'ldaps://vldp.floal:636/'
  2016-04-07 10:32:57 [http-nio-8086-exec-4] DEBUG o.s.s.l.SpringSecurityLdapTemplate - Searching for entry under DN '', base = 'cn=ProxyUsers,cn=fdam,dc=fg,dc=local', filter = '(CN={0},CN=ProxyUsers,CN=fdam,DC=fg,DC=local)'
  2016-04-07 10:32:57 [http-nio-8086-exec-4] DEBUG o.s.s.w.a.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
  </code></pre>
  
  <p>where DN is '', why?</p>