Creating Spring Boot MVC application with AWS DynamoDB in 10 mins

Image
AWS DynamoDB DB is a serverless NOSQL database. You can understand how to build a spring boot Java web MVC application (Game Leaderboard) reading a AWS DynamoDB in 10 mins. Source of the demo code: https://github.com/babysteps-topro/spring-mvc-dynamodb Command to run the project: mvn spring-boot:run Video explain the table design: https://youtu.be/V0GtrBfY7XM Prerequisite: Install the AWS CLI: https://youtu.be/pE-Q_4YXlR0 Video explain the how to create the table: https://youtu.be/sBZIVLlmpxY

Accessing Weblogic Embedded LDAP programmatically by Spring LDAP module

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 by Java language, you can access 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 make use Spring "ldapTemplate" for accessing the Weblogic Embedded LDAP. It encapsulates basic operation for accessing LDAP (e.g. delete LDAP attribute, replacing LDAP attribute, add LDAP attribute). The "ldapTemplate" is injected to the repository class by define the beans in XML (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.ArrayList;
import java.util.List;
import java.util.Map;

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());
 }
}


You can verify 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".

Comments

Unknown said…
Your code is wrong for the getusergroups(). Your code will only retrieve one group, even if the user is part of multiple groups. This is how to get all the groups.

public List getUserGroups(WlsLdapUser user) {
Map groupMmap = null;
String[] groupMapArray = null;
ArrayList results = new ArrayList();
groupMmap = this.getAttrsStartsWith(user.getDn(), "wlsMemberOf");
groupMapArray = groupMmap.get("wlsMemberOf");

if (groupMapArray.length > 0) {
String[] allGroups = null;
for (int count = 0; count < groupMapArray.length; count++) {
allGroups = StringUtils.split(groupMapArray[count], ",");



for (String s : allGroups) {
if (StringUtils.contains(s, "cn=")) {
String aGroup = StringUtils.remove(s, "cn=");
results.add(aGroup);
}
}
}
}
return results;
}
Anonymous said…
thanks for this post
web designing
sameer alwosaby said…
how i can remove user from group please can you post the code

Popular posts from this blog

Sample Apps: Spring data MongoDB and JSF Integration tutorial (PART 1)

Customizing Spring Data JPA Repository

Adding Hibernate Entity Level Filtering feature to Spring Data JPA Repository