title: Spring LDAP - bind for successful connection
body: <p>I'm trying to authenticate and then query our corporate LDAP using Spring LDAP and Spring security. I managed to make authentication work but when I attempt to run search I always get the following exception</p>
  
  <blockquote>
    <p>In order to perform this operation a successful bind must be completed on the connection</p>
  </blockquote>
  
  <p>After much research I have a theory that after I authenticate and before I can query I need to bind to connection. I just don't know what and how?</p>
  
  <p>Just to mention - I can successfully browse and search our LDAP using JXplorer so my parameters are correct.</p>
  
  <p>Here's section of my securityContext.xml</p>
  
  <pre><code>&lt;security:http auto-config='true'&gt;
      &lt;security:intercept-url pattern="/reports/goodbye.html" 
              access="ROLE_LOGOUT" /&gt;
      &lt;security:intercept-url pattern="/reports/**" access="ROLE_USER" /&gt;
      &lt;security:http-basic /&gt;
      &lt;security:logout logout-url="/reports/logout" 
              logout-success-url="/reports/goodbye.html" /&gt;
  &lt;/security:http&gt;
  &lt;security:ldap-server url="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /&gt;
  &lt;security:authentication-manager&gt;
      &lt;security:authentication-provider ref="ldapAuthProvider"&gt;
  &lt;/security:authentication-provider&gt;
  &lt;/security:authentication-manager&gt;
  &lt;!-- Security beans --&gt;
  &lt;bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"&gt;
      &lt;constructor-arg value="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /&gt;
  &lt;/bean&gt;
  &lt;bean id="ldapAuthProvider" 
     class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"&gt;
      &lt;constructor-arg&gt;
          &lt;bean class="foo.bar.reporting.server.security.ldap.LdapAuthenticatorImpl"&gt;
              &lt;property name="contextFactory" ref="contextSource" /&gt;
              &lt;property name="principalPrefix" value="TD\" /&gt;
              &lt;property name="employee" ref="employee"&gt;&lt;/property&gt;
          &lt;/bean&gt;
      &lt;/constructor-arg&gt;
      &lt;constructor-arg&gt;
        &lt;bean class="foo.bar.reporting.server.security.ldap.LdapAuthoritiesPopulator" /&gt;
      &lt;/constructor-arg&gt;
  &lt;/bean&gt;
  &lt;!-- DAOs --&gt;
  &lt;bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"&gt;
    &lt;constructor-arg ref="contextSource" /&gt;
  </code></pre>
  
  <p>
     
        
     </p>
  
  <p>Here's code snippet from <code>LdapAuthenticatorImpl</code> that performs authentication. No problem here:</p>
  
  <pre><code>@Override
  public DirContextOperations authenticate(final Authentication authentication) {
      // Grab the username and password out of the authentication object.
      final String name = authentication.getName();
      final String principal = this.principalPrefix + name;
      String password = "";
      if (authentication.getCredentials() != null) {
          password = authentication.getCredentials().toString();
      }
      if (!("".equals(principal.trim())) &amp;&amp; !("".equals(password.trim()))) {
          final InitialLdapContext ldapContext = (InitialLdapContext)
       this.contextFactory.getContext(principal, password);
          // We need to pass the context back out, so that the auth provider 
          // can add it to the Authentication object.
          final DirContextOperations authAdapter = new DirContextAdapter();
          authAdapter.addAttributeValue("ldapContext", ldapContext);
          this.employee.setqId(name);
          return authAdapter;
      } else {
          throw new BadCredentialsException("Blank username and/or password!");
      }
  }
  </code></pre>
  
  <p>And here's another code snippet from <code>EmployeeDao</code> with my futile attempt to query:</p>
  
  <pre><code>public List&lt;Employee&gt; queryEmployeesByName(String query) 
     throws BARServerException {
      AndFilter filter = new AndFilter();
      filter.and(new EqualsFilter("objectclass", "person"));
      filter.and(new WhitespaceWildcardsFilter("cn", query));
      try {
          // the following line throws bind exception
          List result = ldapTemplate.search(BASE, filter.encode(), 
              new AttributesMapper() {
              @Override
              public Employee mapFromAttributes(Attributes attrs) 
                  throws NamingException {
                  Employee emp = new Employee((String) attrs.get("cn").get(), 
                     (String) attrs.get("cn").get(),
                          (String) attrs.get("cn").get());
                  return emp;
              }
          });
          return result;
      } catch (Exception e) { 
          throw new BarServerException("Failed to query LDAP", e);
      }
  }
  </code></pre>
  
  <p>And lastly - the exception I'm getting</p>
  
  <pre><code>org.springframework.ldap.UncategorizedLdapException: 
      Uncategorized exception occured during LDAP processing; nested exception is 
      javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: 
      DSID-0C090627, comment: In order to perform this operation a successful bind 
      must be completed on the connection., data 0, vece]; remaining name 
      'DC=TD,DC=FOO,DC=COM'
  </code></pre>