Announcement Announcement Module
Collapse
No announcement yet.
In order to perform this operation a successful bind must be completed on the connect Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • In order to perform this operation a successful bind must be completed on the connect

    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

    In order to perform this operation a successful bind must be completed on the connection

    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?

    Just to mention - I can successfully browse and search our LDAP using JXplorer so my parameters are correct.

    Here's section of my securityContext.xml
    Code:
        <security:http auto-config='true'>
            <security:intercept-url pattern="/reports/goodbye.html" 
                    access="ROLE_LOGOUT" />
            <security:intercept-url pattern="/reports/**" access="ROLE_USER" />
            <security:http-basic />
            <security:logout logout-url="/reports/logout" 
                    logout-success-url="/reports/goodbye.html" />
        </security:http>
        <security:ldap-server url="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" />
        <security:authentication-manager>
            <security:authentication-provider ref="ldapAuthProvider">
        </security:authentication-provider>
        </security:authentication-manager>
        <!-- Security beans -->
        <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
            <constructor-arg value="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" />
        </bean>
        <bean id="ldapAuthProvider" 
           class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
            <constructor-arg>
                <bean class="foo.bar.reporting.server.security.ldap.LdapAuthenticatorImpl">
                    <property name="contextFactory" ref="contextSource" />
                    <property name="principalPrefix" value="TD\" />
                    <property name="employee" ref="employee"></property>
                </bean>
            </constructor-arg>
            <constructor-arg>
              <bean class="foo.bar.reporting.server.security.ldap.LdapAuthoritiesPopulator" />
            </constructor-arg>
        </bean>
        <!-- DAOs -->
        <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
          <constructor-arg ref="contextSource" />
       </bean>
       <bean id="employeeDao" class="foo.bar.reporting.data.EmployeeDaoImpl">
          <property name="ldapTemplate" ref="ldapTemplate" />
       </bean>
    Here's code snippet from LdapAuthenticatorImpl that performs authentication. No problem here:
    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())) && !("".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!");
            }
        }
    And here's another code snippet from EmployeeDao with my futile attempt to query:
    Code:
        public List<Employee> 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);
            }
        }
    And lastly - the exception I'm getting
    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'

  • #2
    Looks like you are using Active Directory and it doesn't allow an anonymous bind ("bind" and "authenticate" are kind of equivalent terms in LDAP parlance).

    You probably need to do your search with the same LdapContext that is obtained in the authenticate method. If you check in Jira there are a couple of open issues which relate to improved AD integration.

    Comment


    • #3
      Originally posted by Luke Taylor View Post
      You probably need to do your search with the same LdapContext that is obtained in the authenticate method.
      And how do I do that? I dug through the code and found these lines in LdapTemplate
      Code:
      	public void search(SearchExecutor se, NameClassPairCallbackHandler handler, 
                  DirContextProcessor processor) {
      		DirContext ctx = contextSource.getReadOnlyContext();
                      ...
      I wonder if I need to use DirContext#getContext(String principal, String credentials) instead but I didn't find way to plug that into the search

      Comment

      Working...
      X