<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaChap Blog &#187; ldap</title>
	<atom:link href="http://blog.javachap.com/index.php/tag/ldap/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.javachap.com</link>
	<description>Java and Technology musings for the masses</description>
	<lastBuildDate>Tue, 15 Nov 2011 10:19:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>&#9733; Ldap User Management with Spring LDAP</title>
		<link>http://blog.javachap.com/index.php/ldap-user-management-with-spring-ldap/</link>
		<comments>http://blog.javachap.com/index.php/ldap-user-management-with-spring-ldap/#comments</comments>
		<pubDate>Fri, 25 Dec 2009 16:23:16 +0000</pubDate>
		<dc:creator>JavaChap</dc:creator>
				<category><![CDATA[Top Menu]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.javachap.com/?p=151</guid>
		<description><![CDATA[Java Naming and Directory Interface (JDNI) is the API used for LDAP programming on the Java platform. JNDI makes far too much work of simple procedures, such as ensuring that resources have been properly opened and closed. In addition, most JNDI methods throw checked exceptions, which are time-consuming to handle. Spring LDAP provides a sophisticated [...]]]></description>
			<content:encoded><![CDATA[<p>Java Naming and Directory Interface (JDNI) is the API used for LDAP programming on the Java platform. JNDI makes far too much work of simple procedures, such as ensuring that resources have been properly opened and closed. In addition, most JNDI methods throw checked exceptions, which are time-consuming to handle.</p>
<p><a href="http://www.springsource.org/ldap">Spring LDAP</a> provides a sophisticated wrapper API on top of JNDI to make LDAP Programming easier. Here i will show you on how to write, update and delete entries on ldap server using Spring LDAP.</p>
<p>Download Spring Ldap from <a title="Spring LDAP Download" href="http://www.springsource.com/download/community">http://www.springsource.com/download/community</a></p>
<h2>Spring Configuration</h2>
<p>Create an <code>LdapContextSource</code> and an <code>LdapTemplate</code> object. Configure the ldapServer url, baseDn and optionally userDn, password if anonymous access is not allowed. Also inject the <code>LdapTemplate</code> into DAO.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;contextSource&quot; class=&quot;org.springframework.ldap.core.support.LdapContextSource&quot;&gt;
    &lt;property name=&quot;url&quot; value=&quot;ldap://localhost:389&quot; /&gt;
    &lt;property name=&quot;base&quot; value=&quot;dc=javachap,dc=com&quot; /&gt;
    &lt;property name=&quot;userDn&quot; value=&quot;cn=Manager,dc=javachap,dc=com&quot; /&gt;
    &lt;property name=&quot;password&quot; value=&quot;mypassword&quot; /&gt;
&lt;/bean&gt;

&lt;bean id=&quot;ldapTemplate&quot;&gt;
    &lt;constructor-arg ref=&quot;contextSource&quot; /&gt;
&lt;/bean&gt;

&lt;bean id=&quot;userService&quot;&gt;
    &lt;property name=&quot;ldapTemplate&quot; ref=&quot;ldapTemplate&quot;/&gt;
&lt;/bean&gt;
</pre>
<h2>Domain</h2>
<p>Create a simple user domain interface and implementation which holds the basic information about the user. The information with in this user  object will be persisted to the Ldap.</p>
<pre class="brush: java; title: ; notranslate">
package com.javachap.domain;

public interface User {

    String getUserName();

    void setUserName(String userName);

    String getFirstName();

    void setFirstName(String firstName);

    String getLastName();

    void setLastName(String lastName);

    String getEmail();

    void setEmail(String email);

    String getPassword();

    void setPassword(String password);

    String getDepartment();

    void setDepartment(String departement);

    String[] getGroups();

    void setGroups(String[] groups);
}
</pre>
<pre class="brush: java; title: ; notranslate">
package com.javachap.domain.impl;

import com.javachap.domain.User;

public class UserImpl implements User {

    private static final long serialVersionUID = 7487133273442955818L;

    private String userName;
    private String firstName;
    private String lastName;
    private String email;
    private String password;
    private String department;
    private String groups[];

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String[] getGroups() {
        return groups;
    }

    public void setGroups(String[] groups) {
        this.groups = groups;
    }

    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(&quot;UserImpl[&quot;);
        buffer.append(&quot;id = &quot;).append(id);
        buffer.append(&quot; userName = &quot;).append(userName);
        buffer.append(&quot; email = &quot;).append(email);
        buffer.append(&quot; firstName = &quot;).append(firstName);
        buffer.append(&quot; lastName = &quot;).append(lastName);
        buffer.append(&quot; password = &quot;).append(password);
        buffer.append(&quot;]&quot;);
        return buffer.toString();
    }
}
</pre>
<h2>User DAO</h2>
<p>LdapTemplate is built on the same principles as the JdbcTemplate in Spring JDBC. It completely eliminates the need to worry about creating and closing <code>DirContext</code> and looping through <code>NamingEnumeration</code>. It also provides a more comprehensive unchecked exception hierarchy, built on Spring's <code>DataAccessException</code>.</p>
<pre class="brush: java; title: ; notranslate">
package com.javachap.service;

import java.util.List;

/**
 * UserService
 *
 * @author JavaChap
 */

public interface UserService {

    User getUser(final String email);

    User save(final User user);

    boolean authenticate(final String userName, final String password);

    List&lt;User&gt; getUsers(final String pattern);

    void delete(final User user);
}
</pre>
<pre class="brush: java; title: ; notranslate">
package com.javachap.service.impl;

import java.io.UnsupportedEncodingException;

/**
 * UserService Implementation
 *
 * @author JavaChap
 */

public class UserServiceImpl implements UserService {

    private static final long serialVersionUID = 4889152297004460837L;

    public static final String BASE_DN = &quot;dc=javachap,dc=com&quot;;

    private static class UserAttributesMapper implements AttributesMapper {

        public Object mapFromAttributes(Attributes attrs)
                throws NamingException {
            User user = (User) AppUtils.getBean(&quot;user&quot;);
            if (attrs.get(&quot;uid&quot;) != null) {
                user.setUserName((String) attrs.get(&quot;uid&quot;).get());
            }
            if (attrs.get(&quot;cn&quot;) != null) {
                user.setFirstName((String) attrs.get(&quot;cn&quot;).get());
            }
            if (attrs.get(&quot;sn&quot;) != null) {
                user.setLastName((String) attrs.get(&quot;sn&quot;).get());
            }
            if (attrs.get(&quot;mail&quot;) != null) {
                user.setEmail((String) attrs.get(&quot;mail&quot;).get());
            }
            return user;
        }
    }

    private LdapTemplate ldapTemplate;

    public void setLdapTemplate(final LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    public boolean authenticate(String userName, String password) {
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;)).and(
                new EqualsFilter(&quot;uid&quot;, userName));
        return ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter
                .toString(), password);
    }

    public User getUser(final String userName) {
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;)).and(
                new EqualsFilter(&quot;uid&quot;, userName));
        List&lt;User&gt; users = ldapTemplate.search(DistinguishedName.EMPTY_PATH,
                filter.encode(), new UserAttributesMapper());
        if (!users.isEmpty()) {
            return users.get(0);
        }
        return null;
    }

    public List&lt;User&gt; getUsers(final String pattern) {
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;));
        if (pattern != null) {
            filter.and(new LikeFilter(&quot;uid&quot;, pattern));
        }
        List&lt;User&gt; users = ldapTemplate.search(DistinguishedName.EMPTY_PATH,
                filter.encode(), new UserAttributesMapper());
        return users;
    }

    public User save(final User user) {
        Name dn = buildDn(user);
        ldapTemplate.bind(dn, null, buildAttributes(user));

        // Update Groups
        for (String group : user.getGroups()) {
            try {
                DistinguishedName groupDn = new DistinguishedName();
                groupDn.add(&quot;ou&quot;, &quot;Groups&quot;);
                groupDn.add(&quot;cn&quot;, group);
                DirContextOperations context = ldapTemplate
                        .lookupContext(groupDn);
                context.addAttributeValue(&quot;memberUid&quot;, user.getUserName());
                ldapTemplate.modifyAttributes(context);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return user;
    }

    public User update(final User user) {
        Name dn = buildDn(user);
        ldapTemplate.rebind(dn, null, buildAttributes(user));
        return user;
    }

    public void delete(User user) {
        Name dn = buildDn(user);
        ldapTemplate.unbind(dn);
    }

    private Name buildDn(final User user) {
        DistinguishedName dn = new DistinguishedName();
        dn.add(&quot;ou&quot;, &quot;People&quot;);
        if (user.getDepartment() != null) {
            dn.add(&quot;ou&quot;, user.getDepartment());
        }
        dn.add(&quot;uid&quot;, user.getUserName());
        return dn;
    }

    private Attributes buildAttributes(final User user) {
        Attributes attrs = new BasicAttributes();
        BasicAttribute ocattr = new BasicAttribute(&quot;objectclass&quot;);
        ocattr.add(&quot;person&quot;);
        ocattr.add(&quot;inetOrgPerson&quot;);
        attrs.put(ocattr);
        attrs.put(&quot;cn&quot;, user.getFirstName());
        attrs.put(&quot;sn&quot;, user.getLastName());
        attrs.put(&quot;userPassword&quot;, &quot;{SHA}&quot; + this.encrypt(user.getPassword()));
        attrs.put(&quot;mail&quot;, user.getEmail());

        return attrs;
    }

    private String encrypt(final String plaintext) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance(&quot;SHA&quot;);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e.getMessage());
        }
        try {
            md.update(plaintext.getBytes(&quot;UTF-8&quot;));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.getMessage());
        }
        byte raw[] = md.digest();
        String hash = (new BASE64Encoder()).encode(raw);
        return hash;
    }
}
</pre>
<h2>Util Classes</h2>
<pre class="brush: java; title: ; notranslate">
package com.javachap.utils;
import org.springframework.context.ApplicationContext;

/**
 * The Application Utils
 *
 * @author Vijay Dendukuri
 */

public class AppUtils {

	private static ApplicationContext applicationContext;

    /**
     * Return the application context.
     *
     * @return the application context
     */
    public static ApplicationContext getApplicationContext() {
    	return (applicationContext);
    }

    /**
     * Set the application context.
     *
     * @param context the application context to set.
     */
    public static void setApplicationContext(final ApplicationContext context) {
    	applicationContext = context;
    }

    /**
     * Returns the Bean given the bean name
     * @param name bean name
     * @return bean instance
     */
    public static Object getBean(final String name) {
    	if(applicationContext == null) {
    		throw new IllegalArgumentException(
    				&quot;ApplicationContext is not initialized&quot;);
    	}
    	return applicationContext.getBean(name);
    }
}
</pre>
<pre class="brush: java; title: ; notranslate">
package com.javachap.service;

import static com.javachap.utils.AppUtils.getBean;

/**
 * Service Utilities, exposes the method to get the services
 * @author Vijay Dendukuri
 */

public class ServiceUtils {

	/**
	 * Gets Instance of UserService
	 * @return UserService Instance
	 */
	public static UserService getUserService(){
		return (UserService)getBean(&quot;userService&quot;);
	}
}
</pre>
<h2>Test class</h2>
<pre class="brush: java; title: ; notranslate">
package com.javachap.service.impl;

import org.apache.log4j.BasicConfigurator;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;

import com.javachap.domain.User;
import com.javachap.domain.impl.UserImpl;
import com.javachap.service.ServiceUtils;
import com.javachap.service.UserService;
import com.javachap.utils.AppUtils;

public class Test {

    public static void main(String args[]) {
        BasicConfigurator.configure();
        GenericApplicationContext appContext = new GenericApplicationContext();
        XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(
                appContext);
        xmlReader.loadBeanDefinitions(new ClassPathResource(
                &quot;applicationContext.xml&quot;));
        appContext.refresh();
        AppUtils.setApplicationContext(appContext);

        UserService userService = ServiceUtils.getUserService();
        // User Authenticate
        boolean authenticated = userService.authenticate(&quot;user@javachap.com&quot;,
                &quot;javachap&quot;);
        System.out.println(&quot;Authenticated: &quot; + authenticated);

        // User Save
        User user = new UserImpl();
        user.setUserName(&quot;javachap2&quot;);
        user.setFirstName(&quot;java&quot;);
        user.setLastName(&quot;chap&quot;);
        user.setEmail(&quot;user2@javachap.com&quot;);
        user.setPassword(&quot;chapjava&quot;);
        user.setDepartment(&quot;Engineering&quot;);
        user.setGroups(new String[] { &quot;Admin&quot;, &quot;HudsonAdmin&quot;, &quot;WikiAdmin&quot; });
        userService.save(user);

        // User Get
        user = userService.getUser(&quot;javachap2&quot;);
        System.out.println(&quot;User:&quot; + user);
    }
}
</pre>
<h2>References</h2>
<p><a href="http://today.java.net/article/2006/04/14/ldaptemplate-ldap-programming-java-made-simple">http://today.java.net/article/2006/04/14/ldaptemplate-ldap-programming-java-made-simple</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.javachap.com/index.php/ldap-user-management-with-spring-ldap/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

