Posted by : Hardik Shah Oct 15, 2012



>>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">

    <display-name>Spring Security 3 Tutorial</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
              /WEB-INF/application-security.xml
        </param-value>
    </context-param>
    <!--  Filter for the Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- - Provides core MVC application controller. See eis-servlet.xml. -->
    <servlet>
        <servlet-name>eis</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>eis</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

File : eis-servlet.xml

This file contains Spring MVC configuration,We will create JSPs and Controllers later on.
<?xml version="1.0" encoding="UTF-8"?>

<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 name="/employee/list.html" class="com.hardik4u.web.EmployeeController">
      </bean>

    <bean name="/admin/home.html" class="com.hardik4u.web.AdminController">
      </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>


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.

<?xml version="1.0" encoding="UTF-8"?>
<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">

<global-method-security pre-post-annotations="enabled" />

<http use-expressions="true" access-denied-page="/accessDenied.jsp">
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/employee/**" access="isAuthenticated()" />
        <!-- Allow all other requests. In a real application you should adopt a 
            whitelisting approach where access is not allowed by default -->
        <intercept-url pattern="/**" access="permitAll" />
        <form-login />
        
        <logout logout-success-url="/loggedout.jsp" />
        
        <remember-me />
        <!-- Uncomment to enable X509 client authentication support <x509 /> -->
        <!-- Uncomment to limit the number of sessions a user can have -->
        <session-management invalid-session-url="/timeout.jsp">
            <concurrency-control max-sessions="1"
                error-if-maximum-exceeded="true" />
        </session-management>

    </http>
<!-- User service and password encoding configuration -->
    <beans:bean id="customEncoder" class="com.hardik4u.security.CustomPasswordEncoder" />
    <beans:bean id="customUserService"
        class="com.hardik4u.security.CustomUserDetailService" />

    <authentication-manager>
        <authentication-provider user-service-ref="customUserService">
            <password-encoder ref="customEncoder" />
        </authentication-provider>
    </authentication-manager>

</beans:beans>
 View Part



File : index.jsp
Path: /
<%@ page session="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <link rel="stylesheet" href="<c:url value='/static/css/tutorial.css'/>" type="text/css" />
      <title>Employee Information System - Home</title>
  </head>
<body>
<div id="content">
<h1>Home Page</h1>
<p>
Anyone can view this page.
</p>
<p>
Your principal object is....: <%= request.getUserPrincipal() %>
</p>
<sec:authorize url='/employee/list.html'>
<p>
You can currently access "/employee" URLs.
</p>
</sec:authorize>
<sec:authorize url='/admin/home.html'>
<p>
You can currently access "/admin" URLs.
</p>
</sec:authorize>

<p>
<a href="employee/list.html">Employee List</a></p>
<p><a href="admin/home.html">Admin Home</a></p>
</div>
</body>
</html>
File : accessDenied.jsp
Path: /
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>No Permission</title>
</head>
<body>
<h3>You have no permission to access this page</h3>
<p><a href="../">Home</a></p>
</body>
</html>

File : loggedout.jsp
Path: /
 <%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <title>Logged Out</title>
  </head>
<body>
<div id="content">
<h2>Logged Out</h2>
<p>
You have been logged out. <a href="<c:url value='/'/>">Start again</a>.
</p>
</div>
</body>
</html>


File : timeout.jsp
Path: /
<%@page session="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <title>Session Timeout</title>
  </head>
<body>
<div id="content">
<h2>Invalid Session</h2>
<p>
Your session appears to have timed out. Please <a href="<c:url value='/'/>">start again</a>.
</p>
</div>
</body>
</html>

File : home.jsp 
Path: /WEB-INF/JSP/admin
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Employee Information System - Admin Home</title>
</head>
<body>
<p>This is Admin Home only ROLE_ADMIN have access to this page.</p>

<p><a href="../">Home</a></p>
<p><a href="../j_spring_security_logout">Logout</a></p>
</body>
</html>

File : list.jsp
Path: /WEB-INF/JSP/employee
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Employee Information System - Employee List</title>
</head>
<body>
This page can be viewed by Authentic Person, either have ROLE_USER,ROLE_ADMIN

<p><a href="../">Home</a></p>
<p><a href="../j_spring_security_logout">Logout</a></p>
</body>
</html>
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<emproles> roles;

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

    public List<emproles> getRoles() {
        return roles;
    }

    public void setRoles(List<emproles> 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<grantedauthority> 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<string,employee> 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<string,employee>();
         
        /* create Roles List */
        List roleslist1 = new ArrayList<emproles>();
        roleslist1.add(empRoles1);
        roleslist1.add(empRoles2);
         
        List roleslist2 = new ArrayList<emproles>();
        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

{ 2 comments... read them below or Comment }

  1. Hi Hardik,

    I have sent you mail on your id, Can you please share source code for Part-1 and Part-2 of this tutorial.

    Thanks,
    Vishal Patil

    ReplyDelete
  2. Hi,
    Can you please forward me your email id? I might need the source please.

    Thanks.

    ReplyDelete

- Copyright © Hardik4U - Skyblue - Powered by Blogger - Designed by Johanes Djogan -