About Rajith Delantha

Rajith is an software engineer, open source contributor and love to develop application based on open source projects.

Spring Security Part 1 – Simple Login application with database

What is Spring Security?

Spring security is a framework that provides security solution, handling authentication and authorization at both the web request level and the method level. Spring security handle security in two ways. One is secure web request and other one is restrict access at the URL level. Spring security uses servlet filters.

In this post I’m going to create a simple web application that handle the login authentication and authorization.

Download project : http://www.mediafire.com/?bb9x88uxvkb0uuv or http://dl.dropbox.com/u/7215751/JavaCodeGeeks/SpringSecurityTutorialPart1/spring-security-login-example.rar

Before create the project need to execute some queries to mysql to create a new database , tables and add some sample data.

create-table.sql

 CREATE DATABASE IF NOT EXISTS `spring-test`;  
 -- create user  
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'test';  
 GRANT ALL ON spring-test.* TO 'user'@'localhost';  
 USE `spring-test`;  
 CREATE TABLE USER_DETAILS (  
 USERNAME VARCHAR(10) NOT NULL,  
 PASSWORD VARCHAR(32) NOT NULL,  
 PRIMARY KEY (USERNAME)  
 );  
 CREATE TABLE USER_AUTH (  
 USERNAME VARCHAR(10) NOT NULL,  
 AUTHORITY VARCHAR(10) NOT NULL,  
 FOREIGN KEY (USERNAME) REFERENCES USER_DETAILS(USERNAME)  
 ); 

test-data.sql

 insert into USER_DETAILS values ('user','123');  
 insert into USER_DETAILS values ('admin','admin');  
 insert into USER_AUTH values ('user', 'ROLE_USER');  
 insert into USER_AUTH values ('admin', 'ROLE_ADMIN');  

After that I create a web project using maven and add below dependencies to pom.xml

<properties>
        <spring.version>3.0.5.RELEASE</spring.version>
</properties> 
<dependencies>  
     <dependency>  
       <groupId>javax.validation</groupId>  
       <artifactId>validation-api</artifactId>  
       <version>1.0.0.GA</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-core</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-web</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-webmvc</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework</groupId>  
       <artifactId>spring-jdbc</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <!-- Spring Security -->  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-core</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-web</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-config</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-taglibs</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <dependency>  
       <groupId>org.springframework.security</groupId>  
       <artifactId>spring-security-acl</artifactId>  
       <version>${spring.version}</version>  
     </dependency>  
     <!-- jstl -->  
     <dependency>  
       <groupId>javax.servlet</groupId>  
       <artifactId>jstl</artifactId>  
       <version>1.2</version>  
     </dependency>  
     <!-- MySQL database driver -->  
     <dependency>  
       <groupId>mysql</groupId>  
       <artifactId>mysql-connector-java</artifactId>  
       <version>5.1.9</version>  
     </dependency>  
     <dependency>  
       <groupId>c3p0</groupId>  
       <artifactId>c3p0</artifactId>  
       <version>0.9.1</version>  
     </dependency>  
   </dependencies>  

After that change the web.xml like this

 <!DOCTYPE web-app PUBLIC  
     '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'  
     'http://java.sun.com/dtd/web-app_2_3.dtd' >  
 <web-app>  
   <display-name>spring-security-login</display-name>  
   <servlet>  
     <servlet-name>login</servlet-name>  
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
     <load-on-startup>1</load-on-startup>  
   </servlet>  
   <servlet-mapping>  
     <servlet-name>login</servlet-name>  
     <url-pattern>/</url-pattern>  
   </servlet-mapping>  
   <listener>  
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
   </listener>  
   <context-param>  
     <param-name>contextConfigLocation</param-name>  
     <param-value>  
       /WEB-INF/login-servlet.xml,  
       /WEB-INF/login-security.xml,  
       /WEB-INF/login-service.xml  
     </param-value>  
   </context-param>  
   <!-- 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>  
   <welcome-file-list>  
     <welcome-file>login.jsp</welcome-file>  
   </welcome-file-list>  
 </web-app> 

Now I need to create login-servlet.xml, login-security.xml and login-service.xml spring configuration files. In this example we are using c3p0 connection pool with Mysql database.

Here is the login-servlet.xml file

 <?xml version='1.0' encoding='UTF-8'?>  
 <beans xmlns='http://www.springframework.org/schema/beans'  
     xmlns:context='http://www.springframework.org/schema/context'  
     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/context


http://www.springframework.org/schema/context/spring-context-3.0.xsd'>

   <context:component-scan base-package='rd.controller'/>  
   <bean id='internalResourceResolver'  
      class='org.springframework.web.servlet.view.InternalResourceViewResolver'>  
     <property name='prefix' value='/WEB-INF/views/'/>  
     <property name='suffix' value='.jsp'/>  
   </bean>  
   <bean class='org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping'></bean>  
   <bean class='org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter'/>  
   <bean id='placeholderConfig'  
      class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'>  
     <property name='locations'>  
       <list>  
         <value>classpath:login.properties</value>  
       </list>  
     </property>  
   </bean>  
 </beans>  

Here is the login-security.xml

 <?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'>

   <beans:import resource='login-service.xml'/>  
   <http>  
     <intercept-url pattern='/home*' access='ROLE_USER,ROLE_ADMIN' />  
     <intercept-url pattern='/admin*' access='ROLE_ADMIN' />  
     <form-login login-page='/login.jsp' default-target-url='/home' authentication-failure-url='/login.jsp?error=true'/>  
     <logout logout-success-url='/login.jsp' />  
     <anonymous username='guest' granted-authority='ROLE_GUEST'/>  
     <remember-me/>  
   </http>  
   <authentication-manager>  
     <authentication-provider>  
       <!--<user-service>-->  
         <!--<user name='admin' password='secret' authorities='ROLE_ADMIN,ROLE_USER' />-->  
         <!--<user name='user1' password='1111' authorities='ROLE_USER' />-->  
       <!--</user-service>-->  
       <jdbc-user-service data-source-ref='dataSource'  
           users-by-username-query='select username,password, 'true' as enabled from USER_DETAILS where username=?'  
           authorities-by-username-query='select USER_DETAILS.username , USER_AUTH.AUTHORITY as authorities from USER_DETAILS,USER_AUTH  
            where USER_DETAILS.username = ? AND USER_DETAILS.username=USER_AUTH.USERNAME '/>  
     </authentication-provider>  
   </authentication-manager>  
 </beans:beans>  

Here is the login-service.xml

 <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='com.mchange.v2.c3p0.ComboPooledDataSource'>  
     <!--Driver name to connect to the database-->  
     <property name='driverClass'>  
       <value>${login.jdbc.driver}</value>  
     </property>  
     <!--DB URL-->  
     <property name='jdbcUrl'>  
       <value>${login.url}</value>  
     </property>  
     <!--DB User used to connect to the schema-->  
     <property name='user'>  
       <value>${login.username}</value>  
     </property>  
     <!--Password required to access for the above user-->  
     <property name='password'>  
       <value>${login.password}</value>  
     </property>  
     <!-- configuration pool via c3p0-->  
     <property name='acquireIncrement'>  
       <value>${login.c3p0.acquireIncrement}</value>  
     </property>  
     <property name='idleConnectionTestPeriod'>  
       <value>${login.c3p0.idleConnectionTestPeriod}</value>  
       <!-- seconds -->  
     </property>  
     <property name='maxPoolSize'>  
       <value>${login.c3p0.maxPoolSize}</value>  
     </property>  
     <property name='maxStatements'>  
       <value>${login.c3p0.maxStatements}</value>  
     </property>  
     <property name='minPoolSize'>  
       <value>${login.c3p0.minPoolSize}</value>  
     </property>  
     <property name='initialPoolSize'>  
       <value>${login.c3p0.initialPoolSize}</value>  
     </property>  
     <property name='maxIdleTime'>  
       <value>${login.c3p0.maxIdleTime}</value>  
     </property>  
     <property name='acquireRetryAttempts'>  
       <value>${login.c3p0.acquireRetryAttempts}</value>  
     </property>  
     <property name='acquireRetryDelay'>  
       <value>${login.c3p0.acquireRetryDelay}</value>  
     </property>  
     <property name='breakAfterAcquireFailure'>  
       <value>${login.c3p0.breakAfterAcquireFailure}</value>  
     </property>  
   </bean>  
 </beans>  

The login.jsp page looks like this. (Need to place is under webapp directory. But not in under WEB_INF directory)

 <%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %>  
 <html>  
 <head>  
   <title>Login</title>  
 </head>  
 <body>  
 <c:if test='${not empty param.error}'>  
   <font color='red'>  
     Login error. <br />  
     Reason : ${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}  
   </font>  
 </c:if>  
 <form method='POST' action='<c:url value='/j_spring_security_check' />'>  
   <table>  
     <tr>  
       <td align='right'>Username</td>  
       <td><input type='text' name='j_username' /></td>  
     </tr>  
     <tr>  
       <td align='right'>Password</td>  
       <td><input type='password' name='j_password' /></td>  
     </tr>  
     <tr>  
       <td colspan='2' align='right'>  
         <input type='submit' value='Login' />  
       </td>  
     </tr>  
   </table>  
 </form>  
 </body>  
 </html>

home.jsp page

 <%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %>  
 <%@ taglib prefix='sec' uri='http://www.springframework.org/security/tags' %>  
 <html>  
 <head>  
   <title>Home</title>  
 </head>  
 <body>  
   <a href=<c:url value='/j_spring_security_logout'/>>Logout</a><br/>  
   <sec:authorize ifAnyGranted='ROLE_ADMIN'>  
     <h1>Only admin can see this</h1><br/>  
     <a href='admin'> Admin Home </a>  
   </sec:authorize>  
   <h1>Welcome</h1>  
 </body>  
 </html>  

admin-home.jsp page

 <%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %>  
 <%@ page contentType='text/html;charset=UTF-8' language='java' %>  
 <html>  
 <head>  
   <title>Admin</title>  
 </head>  
 <body>  
   <a href=<c:url value='/j_spring_security_logout'/>>Logout</a><br/>  
   <h1>Only Admin allowed here</h1>  
 </body>  
 </html>  

After that you need to write two controller to retrieve home page and admin-home page. Here is the HomeController.java

 package rd.controller;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RequestMethod;  
 @Controller  
 public class HomeController {  
   @RequestMapping(value = '/home' , method = RequestMethod.GET)  
   public String setUp(Model model){  
     return 'home';  
   }  
 }  

Here is the AdminController.java

 package rd.controller;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RequestMethod;  
 @Controller  
 public class AdminController {  
   @RequestMapping(value = '/admin' , method = RequestMethod.GET)  
   public String setUp(Model model){  
     return 'admin-home';  
   }  
 }  

That’s it. Run mvn clean install command to create war file. Copy the war file under tomcat/webapps directory and access the web app in your favorite browser.
url : localhost:<port>/spring-login/login.jsp

Test case 1 : Try to log with user as username 123 as password. You will get users home page.
Test case 2 : Try to log with admin as username admin as password. You will get users home page with visible admin page link.

In spring security part 2 I will modify this project and add remember me feature and md5 password encryption feature.

In near future Ill try to post some interesting article about spring security with CAS integration and LDAP integration. Stay tuned :)

Reference: Spring Security Part 1 – Simple Login application with database from our JCG partner Rajith Delantha at the Looping around with Rajith… blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

7 Responses to "Spring Security Part 1 – Simple Login application with database"

  1. Download from Mediafire? Seriously?

  2. disqus_LbqUT4n4iD says:

    Hi Can We use this project in Eclipse?

  3. Jitender says:

    Annotations used in both the POJOs doesn’t work.

Leave a Reply


3 − two =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books