Spring Security Tutorial Part-2 (Using Database)

Spring Security using database

In this part, we will implement Spring security authentication via database.

We will apply change to files or add new files on top of  the first part of tutorial.

First we will create tables and fill basic data via below SQL script. It will be used in our example

CREATE TABLE  employee (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT,
  `password` varchar(255) DEFAULT NULL,
  `username` varchar(255) NOT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `username` (`username`)
);
CREATE TABLE  roles (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT,
  `role` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `role` (`role`)
);
DROP TABLE IF EXISTS `springexp`.`employee_roles`;
CREATE TABLE  `springexp`.`employee_roles` (
  `employee_Id` bigint(20) NOT NULL,
  `roles_Id` bigint(20) NOT NULL,
  PRIMARY KEY (`employee_Id`,`roles_Id`),
  KEY `fk_r_id` (`roles_Id`),
  KEY `fk_e_id` (`employee_Id`),
  CONSTRAINT `fk_e_id` FOREIGN KEY (`employee_Id`) REFERENCES `employee` (`Id`),
  CONSTRAINT `fk_r_id` FOREIGN KEY (`roles_Id`) REFERENCES `roles` (`Id`)
);
insert into employee values (1,"hardik","hardik");
insert into employee values (2,"vihan","vihan");

insert into roles values(1,"ROLE_USER");
insert into roles values(2,"ROLE_ADMIN");

insert into employee_roles values (1,1);
insert into employee_roles values (1,2);
insert into employee_roles values (2,1);
commit;

Configuration

File : application-hibernate.xml (New)
location : /WEB-INF

This file contains datasource,hibernate properties and DAO and service layer related beans definition.


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">


    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

       
       
       
       
   


   
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

       
           
       

       
           
                org.hibernate.dialect.MySQLDialect
                true
                update

           
       
       
           
                com.hardik4u.model.Employee
                com.hardik4u.model.EmpRoles
           

       
   

   
   
       
   
   
       
   

   
      
          
      



File : web.xml (Changed)
location : /WEB-INF

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    Spring Security 3 Tutorial
   
        contextConfigLocation
       
              /WEB-INF/application-security.xml
              /WEB-INF/application-hibernate.xml
       
   
   
   
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
   

   
        springSecurityFilterChain
        /*
   

   
        org.springframework.web.context.ContextLoaderListener
   
   
   
        eis
        org.springframework.web.servlet.DispatcherServlet
        1
   

   
        eis
        *.html
   

   
        index.jsp
   

  Java Source

File : Employee.java (changed)

package com.hardik4u.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name="employee")
       
public class Employee implements UserDetails,Serializable {

    @Id
    @GeneratedValue
    private Long Id;
   
    @Column(name="username",unique=true,nullable=false)
    private String username;
   
    @Column(name="password")
    private String password;
   
    @OneToMany(fetch = FetchType.EAGER)
    @Column(name="roles",unique=false)
    private Set roles;

    public Employee()
    {
       
    }
    public Employee(String username, String password, Set roles) {
        this.username = username;
        this.password = password;
        this.roles = roles;
    }

    public Set getRoles() {
        return roles;
    }

    public void setRoles(Set roles) {
        this.roles = roles;
    }

    public boolean isEnabled() {
        return true;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public Collection getAuthorities() {

        List l1 = new ArrayList();

        for (EmpRoles emplRole : roles) {
            l1.add(new GrantedAuthorityImpl(emplRole.getRole()));
        }
        return l1;
    }

   
    @Override
    public String getPassword() {
        return username;
    }

    @Override
    public String getUsername() {
        return password;
    }

}

File : EmpRoles.java (Changed)

package com.hardik4u.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="roles")
public class EmpRoles implements Serializable{

    @Id
    @GeneratedValue
    private Long Id;
       
    private String role;
   
    @Column(name="role",unique=true,nullable=false)
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
   
       
}

File : CustomerUserDetailService.java (Changed)

package com.hardik4u.security;

import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.context.ContextLoader;
import com.hardik4u.model.Employee;
import com.hardik4u.service.EmpServiceImpl;

public class CustomUserDetailService implements UserDetailsService{

   
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
       
        ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); 
        EmpServiceImpl empServiceImpl =(EmpServiceImpl)ctx.getBean("empService"); 
        Employee localEmp = empServiceImpl.getEmployeeByUsername(username);
        return localEmp;
       
    }
   
}


File : EmployeeDAO.java(New File)

package com.hardik4u.dao;

import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.hardik4u.model.Employee;
public class EmployeeDAO {

    private HibernateTemplate hibernateTemplate;

     public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
      this.hibernateTemplate = hibernateTemplate;
     }
   
     public Employee findSampleByCity(String username) {
         List results = hibernateTemplate.find("from Employee"+
           " where username = ?",new Object[] {username});
          return results.size() > 0 ? (Employee) results.get(0) : null;
        }
   
}


you can download source code from the below location.

Download File (eclipse Project)

Hope this will help you my friends. you can get in touch in case of any queries or help.

Cheers 🙂

Spring Security Tutorial Part-1

>>Second Part

Please find below complete example of the spring security 3.we will create employee information system for this example.

In the second part we will implement hibernate and spring security will check credentials from the DB.

If you require source for this example, please get in touch!





Configuration Part

We require below list of jar files for spring security,Spring MVC example.There are several addition jars but it has been added it for future reference.

antlr-2.7.6.jar
aopalliance-1.0.jar
commons-beanutils-1.8.3.jar
commons-codec.jar
commons-collections-3.2.1.jar
commons-configuration-1.7.jar
commons-digester-1.8.1.jar
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
commons-lang-2.6.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
hibernate3.jar
hibernate-annotations-3.5.6-Final.jar
hibernate-commons-annotations-3.2.0.Final.jar
hibernate-core-3.5.6-Final.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar
hibernate-search192762.jar
hibernate-validator-4.1.0.Final.jar
javassist-3.11.0.GA.jar
jstl-1.2.jar
jta.jar
log4j-1.2.16.jar
mysql-connector-java-5.1.18.jar
org.springframework.orm-3.0.1.RELEASE-A.jar
slf4j-api-1.6.4.jar
spring-aop-3.0.6.RELEASE.jar
spring-asm-3.0.6.RELEASE.jar
spring-beans-3.0.6.RELEASE.jar
spring-context-3.0.6.RELEASE.jar
spring-context-support-3.0.6.RELEASE.jar
spring-core-3.0.6.RELEASE.jar
spring-expression-3.0.6.RELEASE.jar
spring-jdbc-3.0.1.RELEASE.jar
spring-security-acl-3.0.2.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-taglibs-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
spring-tx-3.0.1.RELEASE.jar
spring-web-3.0.6.RELEASE.jar
spring-webmvc-3.0.6.RELEASE.jar

File : web.xml

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    Spring Security 3 Tutorial
   
        contextConfigLocation
       
              /WEB-INF/application-security.xml
       
   
   
   
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
   

   
        springSecurityFilterChain
        /*
   

   
        org.springframework.web.context.ContextLoaderListener
   
   
   
        eis
        org.springframework.web.servlet.DispatcherServlet
        1
   

   
        eis
        *.html
   

   
        index.jsp
   


File : eis-servlet.xml

This file contains Spring MVC configuration,We will create JSPs and Controllers later on.



<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

      
     

   
     

   
       
       
   

File : application-security.xml

This file contains the configuration of Spring Security. Here we have created two custom beans for providing customization for application as below:

  • customEncoder – This bean will implement existing password encoder of spring security
  • customUserService – This bean will implement existing user details service of existing spring security.

This two files will perform vital part for authenticate and authorize user via spring security.


<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">




       
       
        <!-- Allow all other requests. In a real application you should adopt a
            whitelisting approach where access is not allowed by default -->
       
       
       
       
       
       
        <!-- Uncomment to enable X509 client authentication support -->
       
       
            <concurrency-control max-sessions="1"
                error-if-maximum-exceeded="true" />
       

   

   
    <beans:bean id="customUserService"
        class="com.hardik4u.security.CustomUserDetailService" />

   
       
           
       
   


 View Part

File : index.jsp
Path: /









 
     
      <link rel="stylesheet" href="" type="text/css" />
      Employee Information System - Home
 


Home Page



Anyone can view this page.



Your principal object is....:




You can currently access "/employee" URLs.





You can currently access "/admin" URLs.





Employee List


Admin Home





File : accessDenied.jsp
Path: /

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>




No Permission


You have no permission to access this page


Home





File : loggedout.jsp
Path: /

 



 
     
      Logged Out
 


Logged Out



You have been logged out. <a href="">Start again.







File : timeout.jsp
Path: /







Session Timeout



Invalid Session



Your session appears to have timed out. Please <a href="">start again.






File : home.jsp 
Path: /WEB-INF/JSP/admin

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>




Employee Information System - Admin Home


This is Admin Home only ROLE_ADMIN have access to this page.



Home


Logout





File : list.jsp
Path: /WEB-INF/JSP/employee

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>




Employee Information System - Employee List


This page can be viewed by Authentic Person, either have ROLE_USER,ROLE_ADMIN

Home


Logout



Java Resources

Model Classes

File : Employee.java
This class is extending the org.springframework.security.core.userdetails.UserDetails class. The reason behind is that Spring’s  UserDetailService class has method loadUserbyUsername – which we are using to authenticate and authorized user via spring security. This method returning UserDetails object of Spring Security. So we can return Employee model object in spite of UserDetails from this method and we can use directly object for other business logic.

package com.hardik4u.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

public class Employee implements UserDetails {

    private String username;
    private String password;
    private List roles;

    public Employee(String username, String password, List roles) {
        this.username = username;
        this.password = password;
        this.roles = roles;
    }

    public List getRoles() {
        return roles;
    }

    public void setRoles(List roles) {
        this.roles = roles;
    }

    public boolean isEnabled() {
        return true;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public Collection getAuthorities() {

        List l1 = new ArrayList();

        for (EmpRoles emplRole : roles) {
            l1.add(new GrantedAuthorityImpl(emplRole.getRole()));
        }
        return l1;
    }

    @Override
    public String getPassword() {
        return username;
    }

    @Override
    public String getUsername() {
        return password;
    }

}


File : EmpRoles.java

package com.hardik4u.model;

public class EmpRoles{

private String role;

public String getRole() {
return role;
}

public void setRole(String role) {
this.role = role;
}

}


Spring Security Extended Classes


File : CustomUserDetailService.java
This class is extending UserDetailsService class of Spring Security. We will extend the method loadUserByUsername method to loadUser in SecurityContext

package com.hardik4u.security;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.hardik4u.model.Employee;
import com.hardik4u.service.EmpServiceImpl;

public class CustomUserDetailService implements UserDetailsService{

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// TODO Auto-generated method stub

EmpServiceImpl empServiceImpl = new EmpServiceImpl();
empServiceImpl.setEmployeeList();
Employee localEmp = empServiceImpl.getEmployeeByUsername(username);

return localEmp;

}

}
 

File : CustomPasswordEncoder.java
This class is used to validate password using spring security. Authentication provider require this bean’s injection.

package com.hardik4u.security;

import org.springframework.security.authentication.encoding.PasswordEncoder;

public class CustomPasswordEncoder implements PasswordEncoder{

@Override
public String encodePassword(String arg0, Object arg1) {
// TODO Auto-generated method stub
return null;
}

@Override
public boolean isPasswordValid(String password, String userInput, Object arg2) {
// TODO Auto-generated method stub
return password.equals(userInput) ? true : false;
}

}

Service layer

File : EmpServiceImpl.java

package com.hardik4u.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.hardik4u.model.EmpRoles;
import com.hardik4u.model.Employee;

public class EmpServiceImpl {

    public Map empList;
    
    public Employee getEmployeeByUsername(String username) {
        
        return empList.get(username);
    }
    
    public void setEmployeeList()
    {
        /* create Roles */
        EmpRoles empRoles1 = new EmpRoles();
        empRoles1.setRole("ROLE_ADMIN");
        
        EmpRoles empRoles2 = new EmpRoles();
        empRoles2.setRole("ROLE_USER");
        
        empList = new HashMap();
        
        /* create Roles List */
        List roleslist1 = new ArrayList();
        roleslist1.add(empRoles1);
        roleslist1.add(empRoles2);
        
        List roleslist2 = new ArrayList();
        roleslist2.add(empRoles2);
        
        /* create Employees */
        Employee emp1 = new Employee("hardik","hardik",roleslist1);
        Employee emp2 = new Employee("vihan","vihan",roleslist2);
    
        empList.put(emp1.getUsername(),emp1);
        empList.put(emp2.getUsername(), emp2);
    }

}



Controllers

File : AdminController.java

package com.hardik4u.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.hardik4u.model.Employee;

public class AdminController implements Controller{

@Override
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
ModelAndView mav = new ModelAndView("admin/home");

// Employee emp = (Employee)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

return mav;
}

}

File : EmployeeController.java

package com.hardik4u.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class EmployeeController implements Controller{

@Override
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
ModelAndView mav = new ModelAndView("employee/list");
return mav;
}

>>Second Part