I have more than 10years of development experience. My expertise is in Java EE technology, object-oriented application development, and use of open source frameworks. In recent years, I mainly worked in development projects of Java EE applications in Weblogic platform with Oracle database. I primarily involved in framework development and architectural design in these projects. Boris is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. You can read more from them at their website. View Full User Profile

Accessing Weblogic Embedded LDAP programmatically by Spring LDAP module

09.05.2012
| 3176 views |
  • submit to reddit

Original Article: http://borislam.blogspot.hk/2012/09/accessing-weblogic-embedded-ldap-with.html 

Oracle Weblogic Application Server includes an embedded LDAP server which acts as the default security provider data store. There are few methods to access the embedded LDAP server. Oracle Weblogic provides an administration console for user to access it. We can create user, create group or edit detail through this administration console.


We could also access the embedded LDAP programmatically. Using WLST (Weblogic Scripting tool) is a standard way to do it but you need have knowledge of Jython programming. Alternatively, if you want to access it through Java, you can programmatically call the Weblogic MBeans directly. However, this is not an easy task. You can see this link for more detail.


In this article, I will show you an alternative way to access the Weblogic Embedded LDAP programmatically with Spring-LDAP. If you are acquainted with Spring, you may find this method quite easy and useful. In the following example, we do simple operation like search user, create user and add user to group through spring "ldaptemplate".

 

 Step 1: Create WlsLdapUser class which represent a LDAP user.

import java.util.HashSet;
import java.util.Set;
import javax.naming.Name;
 
public class WlsLdapUser {
 private String dnFull;
 private String id;
 private String password;
 private Set<String> group;
 private Name dn;
  
 public String getId() {
   return this.id;
 }
  
 public void setId(String id) {
   this.id = id;
 }
  
 public String getPassword() {
   return this.password;
 }
  
 public void setPassword(String password) {
   this.password = password;
 }
 
  
 public Set<String> getGroup() {
   return this.group;
 }
  
 public void setGroup(Set<String> group) {
   this.group = group;
 }
  
 public void addToGroup(String group) {
   if (getGroup() == null)
     setGroup(new HashSet());
   getGroup().add(group);
 }
  
 public void setDnFull(String dn) {
   this.dnFull = dn;
 }
  
 public String getDnFull() {
   return this.dnFull;
 }
  
 public void setDn(Name dn) {
   this.dn = dn;
 }
  
 public Name getDn() {
   return this.dn;
 }
 
 @Override
 public String toString() {
  return "WlsLdapUser [dnFull=" + dnFull + ", id=" + id + ", password="+ password + ", group=" + group + ", dn=" + dn + "]";
 }
 

 

Step 2: Create a base class "BaseLdapRepository" for accessing the Weblogic Embedded LDAP

This class makes use of Spring's "ldapTemplate" for accessing the Weblogic Embedded LDAP. It encapsulates basic operations for accessing LDAP (e.g. delete LDAP attribute, replacing LDAP attribute, add LDAP attribute). The "ldapTemplate" is injected to the repository class by define in the XML in step 4.

import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.ModificationItem;
 
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.LdapTemplate;
 
public class BaseLdapRepository {
 
  private LdapTemplate ldapTemplate ;
 
  public void setLdapTemplate(LdapTemplate ldapTemplate)
  {
      this.ldapTemplate = ldapTemplate;
  }
   
   
  public LdapTemplate getLdapTemplate() {
   return ldapTemplate;
  }
 
  protected void deleteAttr(Name dn, String attrName) {
      List attributes = new ArrayList();
      Attribute attr = new BasicAttribute(attrName);
      ModificationItem item = new ModificationItem(3, attr);
 
      attributes.add(item);
      modify(dn, attributes);
  }
 
  protected void replaceAttr(Name dn, String attrName, String attrVal) {
      List attributes = new ArrayList();
      Attribute attr = new BasicAttribute(attrName);
      attr.add(attrVal);
      ModificationItem item = new ModificationItem(2, attr);
 
      attributes.add(item);
      modify(dn, attributes);
  }
 
  protected void addAttr(Name dn, String attrName, String attrVal) {
      List attributes = new ArrayList();
      Attribute attr = new BasicAttribute(attrName);
      attr.add(attrVal);
      ModificationItem item = new ModificationItem(1, attr);
 
      attributes.add(item);
      modify(dn, attributes);
  }
 
  private void modify(Name dn, List<ModificationItem> attributes) {
   getLdapTemplate().modifyAttributes(dn, (ModificationItem[])attributes.toArray(new ModificationItem[0]));
 
      attributes.clear();
  }
 
  public Map<String, String[]> getAttrsStartsWith(Name dn, String opAttr) {
      return (Map)getLdapTemplate().lookup(dn, new String[] { opAttr }, new ContextMapper()
  {
        public Object mapFromContext(Object ctx)
        {
          DirContextAdapter context = (DirContextAdapter)ctx;
          Attributes attrs = context.getAttributes();
          NamingEnumeration ids = attrs.getIDs();
          Map m = new HashMap();
          try {
            while (ids.hasMore()) {
              String id = (String)ids.next();
              System.out.println("id: " + id);
 
              m.put(id, context.getStringAttributes(id));
            }
          } catch (NamingException e) {
            e.printStackTrace();
          }
          return m;
        }
      });
  }
} 

 

Step 3: Create a repository class to access the Weblogic Embedded LDAP
In order to implement the create(), find(), addUserGroups() and getUserGroups() methods in this LDAP repository class, we must know some Weblogic specific attributes of the Embedded LDAP.

Each user in Embedded LDAP belongs the "top", "person", "origanizationalPerson",  "inetOrgPerson", "wlsUser" objectclass. Therefore, when we implement the create() method, we must make sure the user entry belongs to these objectClasses. Also, each user in Embedded LDAP is under the "People" organization unit (OU). Thus, we need to search under "ou=people" when we find a specific user.

When we add user to groups, we make use of the "uniquemember" attribute in the group entry. On the contrary, when want to know the groups in which a specific user belongs to, we make use if the "wlsMemberOf" attribute in user entry. 

import java.util.Map;
import java.util.ArrayList;
import javax.naming.Name;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.support.AbstractContextMapper;
import org.springframework.ldap.filter.EqualsFilter;
 
 
public class WlsLdapUserRepository extends BaseLdapRepository {
  
 protected DistinguishedName buildDn(WlsLdapUser user) {
     return buildDn(user.getId());
 }
     
 protected DistinguishedName buildDn(String uid) {
     DistinguishedName dn = new DistinguishedName();
     dn.add("ou", "people");
     dn.add("cn", uid);
     return dn;
 }
  
 protected DistinguishedName buildDnGroup(String cn)
 {
     DistinguishedName dn = new DistinguishedName();
    dn.add("ou", "groups");
     dn.add("cn", cn);
     return dn;
 }
  
 public void addToGroup(String dn, String gid) {
      DistinguishedName gdn = buildDnGroup(gid);
  
      super.addAttr(gdn, "uniquemember", dn);
 }
  
 public WlsLdapUser create(WlsLdapUser user)
 {
     Name dn = buildDn(user);
     DirContextAdapter context = new DirContextAdapter(dn);
     context.setAttributeValues("objectclass", new String[] { "top", "person", "inetOrgPerson", "organizationalPerson", "wlsuser" });
     context.setAttributeValue("cn", user.getId());
     context.setAttributeValue("sn", user.getId());
     context.setAttributeValue("uid", user.getId());
     context.setAttributeValue("userPassword", user.getPassword());
     getLdapTemplate().bind(dn, context, null);
     user = find(user.getId());
     return user;
 }
  
 public WlsLdapUser find(String uid) {
     WlsLdapUser user;
     try {      
      user = (WlsLdapUser)getLdapTemplate().searchForObject("ou=people", new EqualsFilter("uid", uid).toString(), new WlsUserContextMapper());
     }
     catch (Exception e)
     {
       e.printStackTrace();
       return null;
     }
     return user;
 }
    
 public List<String> getUserGroups(WlsLdapUser user) {
  Map<String, String[]> groupMmap = null;
  String[] groupMapArray = null ;
  ArrayList<String> results = new ArrayList<String>();
  groupMmap = this.getAttrsStartsWith(user.getDn(), "wlsMemberOf");
  groupMapArray = groupMmap.get("wlsMemberOf");
  if (groupMapArray.length >0) {
    String[] allGroups= StringUtils.split(groupMapArray[0], ",");
    for (String s:allGroups){
     if (StringUtils.contains(s, "cn=")) {
      String aGroup = StringUtils.remove(s,"cn=");
      results.add(aGroup);  
     }
    }
  }
  return results;
 }
  
 private static  class WlsUserContextMapper extends AbstractContextMapper
 {
     protected Object doMapFromContext(DirContextOperations context)
     {
      WlsLdapUser user = new WlsLdapUser();
      user.setId(context.getStringAttribute("uid"));
      user.setDnFull(context.getNameInNamespace());
      user.setDn(context.getDn());
      return user;
     }
 }
}
 

 

 

Step 4: Add your spring application context XML file

The connection details to the Embedded LDAP is put inside this file.

<bean id="contextSource" class="org.springframework.ldap.core.support.DirContextSource">
 <property name="url" value="ldap://127.0.0.1:7001">
 </property>
 <property name="userDn" value="cn=Admin"> 
 </property>
 <property name="password" value="welcome1">
 </property>
 <property name="base" value="ou=myrealm,dc=base_domain">
 </property>
</bean>
 
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
 <constructor-arg ref="contextSource" />
</bean>
 
<bean id="wlsLdapUserRepository" class="org.borislam.ldap.repository.WlsLdapUserRepository">
 <property name="ldapTemplate" ref="ldapTemplate" /></bean>

 

 

Step 5: Test your application with the following code

 

@Named
public class TestLdapService {
 @Inject
 private WlsLdapUserRepository wlsLdapUserRepository;
  
 public void createWlsUser(){
  WlsLdapUser u = new WlsLdapUser();
     u.setId("leonardmessi");
     u.setPassword("welcome1");
     u = this.wlsLdapUserRepository.create(u);
     this.wlsLdapUserRepository.addToGroup(u.getDnFull(), "testGroup");
     this.wlsLdapUserRepository.addToGroup(u.getDnFull(), "Administrators");
  System.out.println("create user :" + u.toString());
 }
  
 public void findWlsUser(String userId){
  WlsLdapUser u = this.wlsLdapUserRepository.find(userId);
  System.out.println("create user :" + u.toString());
 }

After adding the user, you can see the user created by the above program through the Weblogic administration console. Besides, you can also verify by directly login the newly created user "leonardmessi" with password "welcome1".

 

 

 

 

Published at DZone with permission of Boris Lam, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)