Announcement Announcement Module
Collapse
No announcement yet.
Difficulties with Spring LDAP and Active Directory Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Difficulties with Spring LDAP and Active Directory

    Accessing LDAP data on an Active Directory server proved to be a significant challenge for me. I spent several days getting it working, perhaps my experience will be useful to others.

    First I setup an Apache Directory Server with sample data and Apache Studio as detailed here

    http://stefan-seelmann.de/index.php?...vironment.html
    Thanks to Stefan Seelmann.

    After getting my feet wet with LDAP, I attempted Spring LDAP Template following a sample project based on information here

    http://blogs.averconsulting.com/2008...-template.aspx
    Thanks to Mathew Thomas.

    This works fine with Apache DS server, but fails (for me) when adjusted for AD. In practice, the differences are subtle, and required a lot of frustrating trial and error.

    My experience with Spring LDAP (and Spring in general) is very limited, what I'm presenting here may not be 'best practice' material, but it works for me.

    The attached Eclipse project has three packages that mirror the successes of my exploration through Spring LDAP.

    Code:
    com.example.springldaptemplate.ds
    Is a working Apache DS example based on the averconsulting.com exmple.

    Code:
    com.example.springldaptemplate.ad
    Is a working Active Directory example. It's the Apache DS project modified to work with AD. Use a compare tool to see where the projects differer.

    Code:
    com.example.springldaptemplate.hw
    Is a 'Hard Wired' version of the AD project further simplified to eliminate unnecessary complexity.

    Spring @Autowired, in my (not so) humble opinion adds no real advantage to a demo-scale project but does add considerable 'magic' which serves only as an additional barrier to understanding the subject under study.

    Execution by JUnit adds another layer of unnecessary complexity.

    This version has both @Autowired and JUnit removed to show the workings of a Spring LDAP Template/AD project in the simplest and most versatile way.

    This is the text presented below. All three versions are included in the attached zip.

    Enjoy!

    -Glen

    My simplified Hard Wired sample project consists of:

    hw-ldap-context.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:aop="http://www.springframework.org/schema/aop"
    	  xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd">
          <bean id="ldapContextSource" 
    		    class="org.springframework.ldap.core.support.LdapContextSource">
    		    <property name="url" value="ldap://ldap.example.com:389" />
    		    <property name="base" value="dc=example,dc=com" />
    		    <property name="userDn" value="cn=admin,cn=users,dc=example,dc=com" />
    		    <property name="password" value="secret" />
    	  </bean>
    	  <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
    		    <constructor-arg ref="ldapContextSource" />
    		    <property name="ignorePartialResultException" value="true" />
    	  </bean>
    </beans>
    LDAPSample.java - The actual demo code.
    Code:
    package com.example.springldaptemplate.hw;
    
    import java.util.List;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;
    import org.springframework.ldap.core.ContextMapper;
    import org.springframework.ldap.core.DirContextAdapter;
    import org.springframework.ldap.core.LdapTemplate;
    import org.springframework.ldap.filter.AndFilter;
    import org.springframework.ldap.filter.EqualsFilter;
    
    public class LDAPSample
    {
    
        private LdapTemplate ldapTemplate;
        // See LdapTemplate JavaDoc for note on AD referral failure
    
        private Person person;
        
        public LDAPSample()
        {
            Resource resource = new ClassPathResource("hw-ldap-context.xml");
            BeanFactory factory = new XmlBeanFactory(resource);
            ldapTemplate = (LdapTemplate) factory.getBean("ldapTemplate");
        }
        
        private static class PersonContextMapper implements ContextMapper
        {
            public Object mapFromContext(Object ctx)
            {
                DirContextAdapter context = (DirContextAdapter) ctx;
                Person p = new Person();
                p.setFullName(context.getStringAttribute("cn"));
                p.setLastName(context.getStringAttribute("sn"));
                p.setUid(context.getStringAttribute("sAMAccountName"));
                p.setEmployeeNumber(context.getStringAttribute("employeeID"));
                return p;
            }
        }
    
        public Person findByPrimaryKey()
        {
            // String name, String company, String country) {
            String dn = "cn=john doe,cn=Users";
            return (Person) ldapTemplate.lookup(dn, new PersonContextMapper());
        }
    
        public boolean setPersonRecord(String uid) 
        {
            AndFilter andFilter = new AndFilter();
            andFilter.and(new EqualsFilter("objectclass","person"));
            andFilter.and(new EqualsFilter("sAMAccountName",uid));
            List<Person> people = ldapTemplate.search("", andFilter.encode(),new PersonContextMapper());
            if (people.size() > 0)
            {
                person = people.get(0);
                return true;
            }
            return false;
        }
    
        public List getOrgNames()
        {
            return ldapTemplate.list("");
        }
    
        public List getUserNames()
        {
            return ldapTemplate.list("cn=Users");
        }
    
        public String getFullName()
        {
            //return findByPrimaryKey().getFullName();
            return person.getFullName();
        }
    
        public String getLastName()
        {
    
            //return findByPrimaryKey().getLastName();
            return person.getLastName();
        }
    
        public String getUid()
        {
            //return findByPrimaryKey().getUid();
            return person.getUid();
        }
    
        public String getEmployeeNumber()
        {
            //return findByPrimaryKey().getEmployeeNumber();
            return person.getEmployeeNumber();
        }
    }
    Person.java - A POJO containing Person attributes.
    Code:
    package com.example.springldaptemplate.hw;
    
    public class Person
    {
        private String fullName;
        private String lastName;
        private String uid;
        private String employeeNumber;
    
        public String getFullName()
        {
            return fullName;
        }
    
        public void setFullName(String fullName)
        {
            this.fullName = fullName;
        }
    
        public String getLastName()
        {
            return lastName;
        }
    
        public void setLastName(String lastName)
        {
            this.lastName = lastName;
        }
    
        public String getUid()
        {
            return uid;
        }
    
        public void setUid(String uid)
        {
            this.uid = uid;
        }
    
        public String getEmployeeNumber()
        {
            return employeeNumber;
        }
    
        public void setEmployeeNumber(String employeeNumber)
        {
            this.employeeNumber = employeeNumber;
        }
    }

    DriverTestCase.java - A demo caller to exercise LDAPSample
    Code:
    package com.example.springldaptemplate.hw;
    
    public class DriverTestCase
    {
        public static void main(String[] args)
        {
            LDAPSample ldap = new LDAPSample();
            if (ldap.setPersonRecord("jdoe"))
            {
                System.out.println("Organizations: " + ldap.getOrgNames());
                System.out.println("Users: " + ldap.getUserNames());
                System.out.println("Full Name: " + ldap.getFullName());
                System.out.println("Last Name: " + ldap.getLastName());
                System.out.println("UserID: " + ldap.getUid());
                System.out.println("Employee Number: " + ldap.getEmployeeNumber());
            }
            else
            {
                System.out.println("Error");
            }
        }
    }
    Last edited by gihrig; Mar 14th, 2010, 01:16 AM. Reason: Turned problem into solution

  • #2
    I solved the problem. The general approach here is right, There are several small errors of a general nature that prevented the code from running.

    I had just spent way too much time staring at broken code and was missing the obvious ;-)

    Moderator: feel free to delete this thread...

    [edit]
    This post referred to the original non-working original post, which has been replaced by a working example. This post prompted the comments below.
    Last edited by gihrig; Mar 14th, 2010, 12:52 PM. Reason: clarification of earlier changes

    Comment


    • #3
      if you could post a working example that may help others in the future. just a suggestion.

      Comment


      • #4
        second that

        Comment


        • #5
          @djKianoosh
          @asafdav2

          Here you are, the original post has been edited to provide a solution in place of the problem as the original problem post offered nothing of benefit.

          -Glen

          Comment


          • #6
            Spring LDAP and AD

            Excellent code sample, thank you!

            Comment

            Working...
            X