Showing posts with label Weblogic 12c. Show all posts
Showing posts with label Weblogic 12c. Show all posts

Friday, January 4, 2013

CRUD operation on weblogic embedded ldap using spring ldapTemplate, jsf and CDI

here i created a java ee 6 based web application to perform CRUD operation on weblogic embedded ldap. JSF 2.0 and Spring ldapTemplate has been used.

the applicationContext.xml is the same as described in my previous post on weblogic embedded ldap. injection of Spring ldapTemplate via CDI is also similar to that post.

lets look at the codes as they speak a lot more than normal explanation,

the model person is a simple pojo

 package model;  
   
 import java.io.Serializable;  
 import javax.inject.Named;  
 import javax.validation.constraints.Size;  
 import org.hibernate.validator.constraints.NotEmpty;  
  
 /**  
  * @author nayef  
  */  
   
 @Named  
 public class Person implements Serializable {  
     
   @NotEmpty(message = "the uid cant be empty")    
   private String uid;  
     
   @NotEmpty(message = "full name cant be empty")  
   @Size(max =20, min =5, message="you must provide a full name between 5 to 20 characters")  
   private String fullName;  
     
   @NotEmpty(message = "short name cant be empty")  
   @Size(max =10, min =3, message="you must provide a short name between 3 to 10 characters")  
   private String shortName;  
   
   @NotEmpty(message = "the password cant be empty")  
   private String password;  
   
   public String getFullName() {  
     return fullName;  
   }  
   
   public void setFullName(String fullName) {  
     this.fullName = fullName;  
   }  
   
   public String getPassword() {  
     return password;  
   }  
   
   public void setPassword(String password) {  
     this.password = password;  
   }  
   
   public String getShortName() {  
     return shortName;  
   }  
   
   public void setShortName(String shortName) {  
     this.shortName = shortName;  
   }  
   
   public String getUid() {  
     return uid;  
   }  
   
   public void setUid(String uid) {  
     this.uid = uid;  
   }  
   
   @Override  
   public String toString() {  
     return "Person{" + "uid=" + uid + ", fullName=" + fullName + ", shortName=" + shortName + '}';  
   }  
  
 } 


the index page contains links of all the other pages,

   
 <?xml version='1.0' encoding='UTF-8' ?>  
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html">  
   <h:head>  
     <title>starting page</title>  
   </h:head>  
   <h:body>  
      to create  go to <h:link value="create page" outcome="create" />  
     <br/>  
     to search  go to <h:link value="search page" outcome="search" />  
     <br/>  
     for list  go to <h:link value="list page" outcome="list" />  
   </h:body>  
 </html>  
   


the create.xhtml contains a simple form to create

   
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html">  
   
   <head>  
     <title>create person</title>  
   </head>  
   <body>  
     <h:form>  
       <h:outputLabel value="Enter UID " />  
       <h:inputText value="#{personController.person.uid}" />  
   
       <br/>  
   
       <h:outputLabel value="Enter Full Name" />  
       <h:inputText value="#{personController.person.fullName}" />  
   
       <br />  
   
       <h:outputLabel value="Enter short Name" />  
       <h:inputText value="#{personController.person.shortName}" />  
   
       <br/>  
   
       <h:outputLabel value="Enter password" />  
       <h:inputSecret value="#{personController.person.password}" />  
   
       <br/>  
   
       <h:commandButton value="Create" action="#{personController.createPerson}" />  
       <h:commandButton value="Cancel" action="#{personController.cancel}" immediate="true"/>  
   
     </h:form>  
   
     <br/>  
     start page <h:link value="start page" outcome="index" />  
     <br/>  
      
   </body>  
 </html>  


the modify.xhtml is like the following. it contains both options for update and delete.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html">  
   
   <head>  
     <title>modify person</title>  
   </head>  
   <body>  
     <h:form id="modifyForm">  
       <h:outputLabel value="Enter UID " />  
       <h:outputText value="#{personController.person.uid}" />  
   
       <br/>  
   
       <h:outputLabel value="Enter Full Name" />  
       <h:inputText value="#{personController.person.fullName}" />  
   
       <br />  
   
       <h:outputLabel value="Enter short Name" />  
       <h:inputText value="#{personController.person.shortName}" />  
   
       <br />  
       <br/>  
   
       <h:outputLabel value="previous password" />  
       <h:inputSecret id="previousPassword" validator="#{personController.passwordValidator}" required="true">  
           
       </h:inputSecret>  
         
       <br/>  
   
       <h:outputLabel value="Enter password" />  
       <h:inputSecret value="#{personController.person.password}" />  
   
       <br/>  
   
       <h:commandButton value="Modify" action="#{personController.updatePerson}" />  
       <br/>  
       <h:commandButton value="Delete" action="#{personController.deletePerson}" immediate="true"/>  
         
       <br/>  
       <h:commandButton value="Cancel" action="#{personController.cancel}" immediate="true"/>  
   
     </h:form>  
       
   </body>  
 </html>  


the list.xhtml lists all the entries and gives option to load entries for modification

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html">  
   <head>  
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  
     <title>person list</title>  
   </head>  
   <body>  
     <h:form>  
       <h:dataTable value="#{personController.personList}" var="personElement">  
         <h:column>  
           #{personElement.uid}  
         </h:column>  
         <br/>  
         <h:column>  
           #{personElement.fullName}  
         </h:column>  
         <br/>  
         <h:column>  
           #{personElement.shortName}  
         </h:column>  
         <br/>  
         <h:column>  
   
           <h:commandLink action="#{personController.loadPersonFromList(personElement.uid)}" value="load">  
   
           </h:commandLink>  
         </h:column>  
   
       </h:dataTable>  
     </h:form>  
     <br/>  
     to create  go to <h:link value="create page" outcome="create" />  
     <br/>  
     start page <h:link value="start page" outcome="index" />  
   </body>  
 </html>  
   


the search.xhtml lets you search entries using uid.

   
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html">  
   <head>  
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  
     <title>Search</title>  
   </head>  
   <body>  
  <h:form>  
   <h:outputLabel value="Enter your uid" />  
   <h:inputText value="#{personController.searchUid}" />  
   
   
   <h:commandButton value="Submit"  
            action="#{personController.loadPerson}" />  
 </h:form>  
     <br/>  
     start page <h:link value="start page" outcome="index" />  
   </body>  
 </html>  
   


failure notification page,

   
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:h="http://java.sun.com/jsf/html"  
    xmlns:f="http://java.sun.com/jsf/core">  
     
   <head>  
     <title>failed</title>  
   </head>  
   <body>  
     <h1>failed</h1>  
      <br/>  
     start page <h:link value="start page" outcome="index" />  
   </body>  
 </html>  
   
the controller for this CRUD operation is as follows,
package Controller;

import Dao.PersonDaoImpl;
import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.inject.Inject;
import javax.inject.Named;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import model.Person;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;

/**   
 *   
 * @author nayef   
 */
@Named
@ConversationScoped
public class PersonController implements Serializable {

    @Valid
    @NotNull
    private Person person = new Person();
    @NotNull
    String searchUid;
    @Inject
    private PersonDaoImpl dao;
    @Inject
    private Conversation conversation;
    @Inject
    private LdapTemplate ldapTemplate;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getSearchUid() {
        return searchUid;
    }

    public void setSearchUid(String searchUid) {
        this.searchUid = searchUid;
    }

    public LdapTemplate getLdapTemplate() {
        return ldapTemplate;
    }

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

    public List<Person> getPersonList() {

        List<Person> personList = dao.findAll();

        return personList;
    }

    public String createPerson() {

        try {
            dao.create(person);
        } catch (Exception e) {
            return "actionFailed?faces-redirect=true";
        }

        return "list?faces-redirect=true";

    }

    public String loadPerson() {

        beginConversation();

        try {
            Person tempPerson = dao.findPersonByUid(searchUid);
            this.person = tempPerson;

        } catch (Exception e) {

            endConversation();
            if (e instanceof org.springframework.ldap.NameNotFoundException) {
            } else {
                System.out.println(e.toString());
            }

            return "actionFailed?faces-redirect=true";
        }

        return "modify?faces-redirect=true";
    }

    public String updatePerson() {
        try {
            dao.updatePersonByUid(this.getPerson());
        } catch (Exception e) {
            endConversation();
            return "actionFailed?faces-redirect=true";
        }

        endConversation();
        return "list?faces-redirect=true";
    }

    public String loadPersonFromList(String uid) {

        beginConversation();
        try {
            Person tempPerson = dao.findPersonByUid(uid);
            this.person = tempPerson;

        } catch (Exception e) {
            conversation.end();
            endConversation();
            return "actionFailed?faces-redirect=true";
        }

        return "modify?faces-redirect=true";

    }

    public String deletePerson() {
        try {
            dao.deletePersonByUid(this.getPerson());
        } catch (Exception e) {
            endConversation();
            return "actionFailed?faces-redirect=true";
        }

        endConversation();
        return "list?faces-redirect=true";
    }

    public String loadPersonList() {
        endConversation();
        return "list?faces-redirect=true";

    }

    public String cancel() {
        endConversation();
        return "index?faces-redirect=true";
    }

    public void passwordValidator(FacesContext context, UIComponent toValidate, Object value) {

        String uid = this.getPerson().getUid();
        String password = (String) value;
        if (password == null || password.trim().length() < 1) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "previous Password cant be empty", "previous Password cant be empty");
            throw new ValidatorException(message);
        }
        if (!loginExistsInLdap(uid, password.trim())) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "previous password not correct", "previous password not correct");
            throw new ValidatorException(message);
        }
    }

    public boolean loginExistsInLdap(String uid, String password) {
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("uid", uid));
        boolean legit = false;

        try {
            legit = this.ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), password);
        } catch (Exception e) {
            legit = false;
        }

        return legit;

    }

    private void beginConversation() {
        if (conversation.isTransient()) {
            conversation.begin();
        }
    }

    private void endConversation() {
        if (!conversation.isTransient()) {
            conversation.end();
        }
    }
}



the dao layer is like this

package Dao;

import java.util.List;
import model.Person;

/**
 *
 * @author nayef
 */
public interface PersonDao {

    public void create(Person p);

    public void updatePersonByUid(Person p);

    public void delete(Person p);

    public Person findPersonByUid(String uid);

    public List<Person> findAll();
}



dao layer implementation uses spring LdapTemplate for ldap operations


package Dao;

import java.io.Serializable;
import java.util.List;
import javax.inject.Inject;
import javax.naming.Name;
import model.Person;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.EqualsFilter;

/**
 *
 * @author nayef
 */
public class PersonDaoImpl implements PersonDao, Serializable {

    @Inject
    private LdapTemplate ldapTemplate;

    public void setLdapTemplate(LdapTemplate l) {
        ldapTemplate = l;
    }

    @Override
    public void create(Person p) {
        DirContextAdapter context = new DirContextAdapter();
        mapToContext(p, context);
        ldapTemplate.bind(buildDn(p), context, null);
    }

    @Override
    public void delete(Person p) {
        ldapTemplate.unbind(buildDn(p));
    }

    @Override
    public List<person> findAll() {
        EqualsFilter filter = new EqualsFilter(
                "objectclass", "person");
        return ldapTemplate.search(
                DistinguishedName.EMPTY_PATH,
                filter.encode(), getContextMapper());
    }

    @Override
    public void updatePersonByUid(Person person) {
        DistinguishedName dn = new DistinguishedName();
        dn.add("ou", "people");
        dn.add("uid", person.getUid());

        DirContextAdapter context = (DirContextAdapter) ldapTemplate.lookup(dn);
        mapToContext(person, context);
        ldapTemplate.modifyAttributes(dn, context.getModificationItems());
    }

    @Override
    public Person findPersonByUid(String uid) {
        DistinguishedName dn = new DistinguishedName();
        dn.add("ou", "people");
        dn.add("uid", uid);
        return (Person) ldapTemplate.lookup(dn, getContextMapper());
    }

    public void deletePersonByUid(Person person) {
        DistinguishedName dn = new DistinguishedName();
        dn.add("ou", "people");
        dn.add("uid", person.getUid());
        ldapTemplate.unbind(dn);
    }

    protected ContextMapper getContextMapper() {
        return new PersonContextMapper();
    }

    protected Name buildDn(Person p) {
        DistinguishedName dn = new DistinguishedName();

        dn.add("ou", "people");
        dn.add("uid", p.getUid());
        return dn;
    }

    protected void mapToContext(Person p, DirContextAdapter context) {
        context.setAttributeValues("objectclass", new String[]{"top",
                    "person", "inetOrgPerson", "organizationalPerson", "wlsuser"});
        context.setAttributeValue("cn", p.getFullName());
        context.setAttributeValue("sn", p.getShortName());
        context.setAttributeValue("uid", p.getUid());
        context.setAttributeValue("userPassword", p.getPassword());


    }

    private static class PersonContextMapper implements ContextMapper {

        @Override
        public Object mapFromContext(Object ctx) {
            DirContextAdapter context = (DirContextAdapter) ctx;
            Person p = new Person();
            p.setFullName(context.getStringAttribute("cn"));
            p.setShortName(context.getStringAttribute("sn"));
            p.setUid(context.getStringAttribute("uid"));
            return p;
        }
    }
}



References

1. https://blogs.oracle.com/jamesbayer/entry/look_inside_weblogic_server_em
2. http://today.java.net/pub/a/today/2006/04/18/ldaptemplate-java-ldap-made-simple.html
3. http://www.jayway.com/2009/02/02/simple-authentication-using-spring-ldap/

Thursday, December 20, 2012

Authentication Using Weblogic Embedded Ldap

Here we use the Weblogic embedded Ldap for authentication purpose of our java EE 6 application. JSF is used as view technology. For communicating with ldap, springLdap library has been used.

Pre requisites: you need an installed weblogic server and its Embedded Ldap properly set.

The spring beans for ldapTemplate are described in the applicationContext.xml
  
<?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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
    
    <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="adminpass0">
        </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>
    
</beans>

the view page for login is a simple xhtml file with two input fields

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    
    <head>
        <title>login page</title>
    </head>
<body>
<h:form>
    <h:outputLabel value="Enter your user ID " />
    <h:inputText value="#{loginController.uid}" />

    <h:outputLabel value="Enter your password" />
    <h:inputSecret value="#{loginController.password}" />
    
    <h:commandButton value="Submit"
                     action="#{loginController.checkLogin}" />
</h:form>
   
</body>
</html>

controller for logging contains methods for authentication.



package Controller;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;

/**
 * @author nayef
 */
@Named
@RequestScoped
public class LoginController {

    @NotEmpty(message = "the uid cant be empty")
    private String uid;
    @NotEmpty(message = "the password cant be empty")
    private String password;
    @Inject
    private LdapTemplate ldapTemplate;

   // getters setters need be here.  

    public String checkLogin() {
        if (loginFromLdap()) {
            return "success?faces-redirect=true";
        } else {
            return "failed?faces-redirect=true";
        }
    }

    public boolean loginFromLdap() {
        AndFilter filter = new AndFilter();
        filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("uid", this.getUid()));
        boolean legit = false;

        try {
            legit = this.ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH, filter.toString(), this.getPassword());
        } catch (Exception e) {
            legit = false;
        }

        return legit;

    }
}


the injected ldapTemplate is produced using a producer method described in injecting-spring-bean-using-cdi .

the success page and failure pages just display the outcome of the authentication.


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <head>
        <title>Success</title>
    </head>
    <body>
        <div>your credentials were found in ldap</div>
    </body>
</html>


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <head>
        <title>Failure</title>
    </head>
    <body>
        <div>your credentials were NOT found in ldap</div>
    </body>
</html>


Resources:
1. http://www.jayway.com/2009/02/02/simple-authentication-using-spring-ldap/
2. http://today.java.net/pub/a/today/2006/04/18/ldaptemplate-java-ldap-made-simple.html
3. http://java.dzone.com/articles/accessing-weblogic-embedded
4. https://blogs.oracle.com/jamesbayer/entry/look_inside_weblogic_server_em
5. http://nayefreza.blogspot.com/2012/12/injecting-spring-bean-using-cdi.html