Enterprise Java

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
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

1
2
3
4
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

1
2
3
<properties>
        <spring.version>3.0.5.RELEASE</spring.version>
</properties>
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE web-app PUBLIC 
    '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 
<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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version='1.0' encoding='UTF-8'?> 
    xsi:schemaLocation=' 
  <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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version='1.0' encoding='UTF-8'?> 
       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 
  <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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  <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)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%@ 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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<%@ 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

01
02
03
04
05
06
07
08
09
10
11
<%@ 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

01
02
03
04
05
06
07
08
09
10
11
12
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

01
02
03
04
05
06
07
08
09
10
11
12
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.

Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Rajith Delantha

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


This site uses Akismet to reduce spam. Learn how your comment data is processed.

16 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Henning Hoefer
12 years ago

Download from Mediafire? Seriously?

Ilias Tsagklis
Ilias Tsagklis
12 years ago
Reply to  Henning Hoefer

Added a dropbox link of the project archive for your convenience.

disqus_LbqUT4n4iD
disqus_LbqUT4n4iD
11 years ago

Hi Can We use this project in Eclipse?

Rajith
Rajith
10 years ago

Yes this is a maven project.

Jitender
Jitender
10 years ago

Annotations used in both the POJOs doesn’t work.

Rajith
Rajith
10 years ago
Reply to  Jitender

You may need to add following line to login-servlet.xml

Underdog Racing Development

It’s difficult to find well-informed people for this subject, however, yoou see like you know what you’re talking
about! Thanks

Manpreet
Manpreet
10 years ago

Awesome tutorial! Thanks for sharing this wonderful sample project. Hope to see more such contributions from you.

Arun
Arun
10 years ago

Hi Rajith … i’m developing login module using Angularjs with MySql database….
already developed Ui and java backend coding …
but i get stuck in calling Rest Service via Angularjs controller using json object ??

David
David
10 years ago

Hi.

If I import this project into STS 3.5.1 I get several erros in:
pom.xml
login-service.xml
web.xml

etc…

Could you please take a look if this project will work into STS?..

Thanks

pavankumar
pavankumar
10 years ago

Thanks for the Great tutorial.

Kong
Kong
10 years ago

I can’t seem to import the project. How do I get it to work?

fardad
9 years ago

hi,excusme can i use pgAdmin database in this project??

Dani
9 years ago

There is definately a lot too find out about this
topic. I really like all of the points you made.

Michael Calcagni
Michael Calcagni
9 years ago

I can still hit the back button and reach to admin only page after I’ve logged out. How can I prevent this
in the least many steps? Great project really works well.

Back to top button