Spring security entry point and role base login example

First I would recommend you to go through my previous blog post I have written for Spring Security hello world example.
Today I am going to explain a simple example of why to use entry point in spring security and how to use role based login in Spring Security 4.

First we will see a spring security flow diagram of today's implementation


In the above diagram, when user log-in by providing credentials then spring filter will evaluate user creds with the help of user details service provider.If user is authenticated successfully then spring filter will invoke success handler  else failure handler.If success then success handler will redirect to page based on his roles.If authentication failure then failure handler will redirect to access denied page.
If none of the user is logged in, then for every request Spring Security handles  the authentication process with the concept of an Entry Point.For any request to the application entry point will redirect to the login page.

let us see implementation of the above diagram

Technologies used 

java 1.7

tomcat 8

spring 4.1.6.RELEASE

spring-security 4.0.1.RELEASE

Maven 3

Maven dependencies

<properties>
        <spring-version>4.1.6.RELEASE</spring-version>
        <spring-orm-version>4.1.1.RELEASE</spring-orm-version>
        <spring-security-version>4.0.1.RELEASE</spring-security-version>
        <hibernate.version>4.3.11.Final</hibernate.version>
        <mysql.driver.version>5.1.30</mysql.driver.version>
    </properties>

    <dependencies>

        <!-- spring dependencies -->
        <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-orm</artifactId>
            <version>${spring-orm-version}</version>
        </dependency>

        <!-- spring security dependencies -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring-security-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security-version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>spring-security-entry-point-and-role-based-url</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Security Configuration XML


Lets look at the configuration xml. I assume that you have clear idea about spring security configuration so I’m not going to explain each and every thing on this project. If you have doubt about the spring configurations please follow my previous posts.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:security="http://www.springframework.org/schema/security"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/security
                http://www.springframework.org/schema/security/spring-security.xsd">

    <context:component-scan base-package="com.spring.security"/>

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

    <!-- Application entry point which will redirect to login if user is not authenticated -->
    <bean id="appAuthenticationEntryPoint" class="com.spring.security.entrypoint.AppAuthenticationEntryPoint">
        <constructor-arg name="loginFormUrl" value="/services/login"/>
    </bean>

    <!-- if user authentication is successful then AppSuccessHandler will redirect to page based on role-->
    <bean id="successHandler" class="com.spring.security.handler.AppSuccessHandler"/>

    <!-- if user authentication is unsuccessful then failureHandler will redirect to access denied page-->
    <bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <constructor-arg name="defaultFailureUrl" value="/services/accessdenied"/>
    </bean>

    <!-- With out login below url can be accessed and they are public,hence security is none -->
    <security:http pattern="/services/login" security="none"/>
    <security:http pattern="/services/accessdenied" security="none"/>

    <!-- Observe entry-point-ref is configured and all the request /** should be authenticated, if any request is not authenticated then entry point will be invoked which intern redirect to login page  -->
    <security:http auto-config="true" use-expressions="true" entry-point-ref="appAuthenticationEntryPoint">
        <!-- Interceptor urls -->
        <security:intercept-url pattern="/" access="isAuthenticated()"/>
        <security:intercept-url pattern="/**" access="isAuthenticated()"/>
        <security:intercept-url pattern="/user**" access="hasRole('USER')" />
        <security:intercept-url pattern="/admin**" access="hasRole('ADMIN')" />

        <security:form-login login-page="/login"
                             login-processing-url="/j_spring_security_check"
                             authentication-success-handler-ref="successHandler"
                             authentication-failure-handler-ref="failureHandler"
                             username-parameter="username"
                             password-parameter="password"
                />

        <!-- disabling csrf protection -->
        <security:csrf disabled="true"/>
    </security:http>


    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider>
            <security:user-service>
                <security:user name="testuser" password="testuser" authorities="ROLE_USER" />
                <security:user name="admin" password="admin" authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

here Spring Security user credentials are placed in XML configuration. However it is not safe to keep user details in XML file,it is always better to use database to secure user creds.I recommend my previous article for spring security using database.

Spring Security handles this automatic triggering of the authentication process with the concept of an Entry Point – this is a required part of the configuration, and can be injected via the entry-point-ref attribute of the security:http  element.

Spring Security handles success handler & failure handler based on authentication result.Success handler and failure handler can be configured in security:form-login element.We use SimpleUrlAuthentication FailureHandler which is provided by spring, which will auto redirect to the access denied page.


EntryPoint :

We need to create a class that will extend Spring’s AuthenticationEntryPoint class and override its method commence to redirect when authentication header is not present in the request.By default This method will reject every unauthenticated request and send error code 401.

AppAuthenticationEntryPoint.java

public class AppAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    public AppAuthenticationEntryPoint(final String loginFormUrl) {
        super(loginFormUrl);
    }

    /**
     * Performs the redirect (or forward) to the login form URL.
     */
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException, ServletException {

        // redirect to login page. Use https if forceHttps true
        String redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
        redirectStrategy.sendRedirect(request, response, redirectUrl);
    }

}

If we didn’t set this handler then spring framework push the 403 Forbidden in response. We can even set unauthrozied(401) in response header as authException.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");

Authentication Success Handler :

AppSuccessHandler.java

public class AppSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException {
        String targetUrl = determineTargetUrl(authentication);

        if (response.isCommitted()) {
            System.out.println("Can't redirect");
            return;
        }

        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    /*
     * This method extracts the roles of currently logged-in user and returns
     * appropriate URL according to his/her role.
     */
    protected String determineTargetUrl(Authentication authentication) {
        String url = "";

        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

        List<String> roles = new ArrayList<String>();

        for (GrantedAuthority a : authorities) {
            roles.add(a.getAuthority());
        }

        if (isAdmin(roles)) {
            url = "/services/adminpage";
        } else if (isUser(roles)) {
            url = "/services/userpage";
        } else {
            url = "/services/accessDenied";
        }

        return url;
    }

    private boolean isUser(List<String> roles) {
        if (roles.contains("ROLE_USER")) {
            return true;
        }
        return false;
    }

    private boolean isAdmin(List<String> roles) {
        if (roles.contains("ROLE_ADMIN")) {
            return true;
        }
        return false;
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }

    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }

}

When authentication is successful then this handler will invoked and redirect to the page as configured in the determineTargetUrl api based on role.

AppController :

This controller will serve your request for login,logout,userpages and redirects to dynamic jsp page.

public class AppController {

    @RequestMapping(value = {"/userpage"}, method = RequestMethod.GET)
    public ModelAndView userPage() {

        if (isAdminPage())
            return adminPage();
        ModelAndView model = new ModelAndView();
        model.addObject("title", "Spring Security Hello World");
        model.addObject("user", getUser());
        model.setViewName("user");
        return model;
    }

    @RequestMapping(value = "/adminpage", method = RequestMethod.GET)
    public ModelAndView adminPage() {
            ModelAndView model = new ModelAndView();
            model.addObject("title", "Spring Security Hello World");
            model.addObject("user", getUser());
            model.setViewName("admin");
            return model;
    }

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{
        ModelAndView model = new ModelAndView();
        model.addObject("title", "Login Page");
        model.setViewName("login");
        return model;
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public ModelAndView logout(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return login(request,response);
    }

    @RequestMapping(value = {"/accessdenied"}, method = RequestMethod.GET)
    public ModelAndView accessDeniedPage() {
        ModelAndView model = new ModelAndView();
        model.addObject("message", "Either username or password is incorrect.");
        model.setViewName("accessdenied");
        return model;
    }

    private String getUser() {
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            userName = ((UserDetails) principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }


    private boolean isAdminPage() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            Collection<? extends GrantedAuthority> authorities = ((UserDetails) principal).getAuthorities();
            if (authorities.size() == 1) {
                final Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
                GrantedAuthority grantedAuthority = iterator.next();
                if (grantedAuthority.getAuthority().equals("ADMIN")) {
                    return true;
                }
            }
        }
        return false;
    }
}

Views :

Login.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>${title}</title>
        <style>
            //removing style,you can see complete css in the attached source.
        </style>
</head>
<body>
<br/><br/><br/><br/><br/><br/><br/>
<div class="login-block">
    <form name='loginForm'
                  action="<c:url value='../j_spring_security_check' />" method='POST'>
        <h1>Login</h1>
        <input type="text" id="username" name="username" placeholder="Username"  />
        <input type="password" id="password" name="password" placeholder="Password" />
        <button>Submit</button>
    </form>
</div>
</body>
</html>

AccessDenied.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Access Denied Page</title>
</head>
<body>
    <h2> Access Denied </h2>
    <br/>${message}<br/>

    Click here for<a href="<c:url value="/login" />"> Login</a>
</body>
</html>

Admin.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld page</title>
</head>
<body>
    ${title}<br/><br/>
    Dear ${user}, you are successfully logged into this application as admin.
    <br/>
    <a href="<c:url value="/services/logout" />">Logout</a>
</body>
</html>

User.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld page</title>
</head>
<body>
    ${title}<br/><br/>
    Dear ${user}, you are successfully logged into this application.
    <br/>
    <a href="<c:url value="/services/logout" />">Logout</a>
</body>
</html>

Screens :

After deploying above application(spring-security-entry-point-and-role-based-url.war) in web server(tomcat) and you can find below screens

Login page :



Entry Point Redirecting to Login page :


Access Denied :


Admin Login :


Download Source : 

Please download source from GitHub.

Spring Security custom login using MySQL DB and Hibernate

Introduction :

This is a step-by-step tutorial that helps you build a Spring security-Hibernate application easily in a clear and concise way.This article is all about implementing Spring Security with custom login in your Spring MVC web application to secure a URL access with  database authentication using hibernate.
In my previous article,I explained Spring Security by placing user credentials in XML configuration. How ever it is not safe to keep user details in XML file.So let us use database to secure & maintain authentication and authorization details.

Technologies used :

java 1.7
tomcat 8
spring 4.1.6.RELEASE
spring-security 4.0.1.RELEASE
Hibernate 4.3.11.Final
Mysql DB (driver version 5.1.30)
Maven 3

Step 1: Maven dependencies

    <properties>
        <spring-version>4.1.6.RELEASE</spring-version>
        <spring-orm-version>4.1.1.RELEASE</spring-orm-version>
        <spring-security-version>4.0.1.RELEASE</spring-security-version>
        <hibernate.version>4.3.11.Final</hibernate.version>
        <mysql.driver.version>5.1.30</mysql.driver.version>
    </properties>

    <dependencies>

        <!-- spring dependencies -->
        <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-orm</artifactId>
            <version>${spring-orm-version}</version>
        </dependency>

        <!-- spring security dependencies -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring-security-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security-version}</version>
        </dependency>

        <!-- hibernate dependencies -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- mysql driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.driver.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>spring-security-custom-login-using-hibernate</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
We use maven-compiler-plugin to compile source using java 1.7 and finalName represents war file name.

Step 2: Login Database Diagram &  Script's :

At first we use two tables USER & ROLE.As single user can have multiple roles and each role can be part of multiple users, so there is MANY to MANY association between USER and ROLE.And database diagram looks like 


Database scripts for above diagram 


create table USER (
 USER_ID varchar(255) not null, 
 ACTIVE integer not null, 
 NAME varchar(32) not null, 
 PASSWORD varchar(64) not null,
 primary key (USER_ID))

create table ROLE (
 ROLE_ID integer not null auto_increment, 
 NAME varchar(32) not null, 
 primary key (ROLE_ID))

create table USER_ROLE (
 USER_ID varchar(255) not null, 
 ROLE_ID integer not null, 
 primary key (USER_ID, ROLE_ID))

alter table USER_ROLE add constraint FK_oqmdk7xj0ainhxpvi79fkaq3y foreign key (ROLE_ID) references ROLE (ROLE_ID)

alter table USER_ROLE add constraint FK_j2j8kpywaghe8i36swcxv8784 foreign key (USER_ID) references USER (USER_ID)

Step 3: Defining Hibernate Entity Model's :

For the above database table, Hibernate entity models look's like

User.java :

@Entity
@Table(name = "USER")
public class User implements Serializable{

    @Id
    @Column(name = "USER_ID", unique = true, nullable = false)
    private String userId;

    @Column(name = "NAME", nullable = false, length = 32)
    private String name;

    @Column(name = "PASSWORD", nullable = false, length = 64)
    private String password;

    @Column(name = "ACTIVE", nullable = false, length = 1)
    private Integer active;

    @ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinTable(
            name = "USER_ROLE",
            joinColumns = @JoinColumn(name = "USER_ID"),
            inverseJoinColumns = @JoinColumn(name = "ROLE_ID")
    )
    private Set<Role> roles = new HashSet<>();

//setters and getters

}

Role.java : 

@Entity
@Table(name = "ROLE")
public class Role implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ROLE_ID", unique = true, nullable = false)
    private Integer roleId;

    @Column(name = "NAME", nullable = false, length = 32)
    private String name;

    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<>();

//setters and getters

}

Step 4: Configure Custom Login  & intercept URL's :

If you want to use a custom login page for your application, then you can configure spring-security to use your custom login page instead. You can use the <security:form-login> tag to define your custom login form page within the <security:http> … </security:http> tag. Below is the configuration example.

    <security:http auto-config="true" use-expressions="true">
        <!-- Interceptor urls -->
        <security:intercept-url pattern="/" access="permitAll" />
        <security:intercept-url pattern="/userpage" access="hasRole('USER')" />
        <security:intercept-url pattern="/admin**" access="hasRole('ADMIN')" />

        <security:form-login login-page="/login"
                             default-target-url="/userpage"
                             login-processing-url="/j_spring_security_check"
                             authentication-failure-url="/accessdenied"
                             username-parameter="username"
                             password-parameter="password"
                />

        <!-- Logout -->
        <security:logout logout-success-url="/logout" />

        <!-- enable csrf protection -->
        <security:csrf/>
    </security:http>


login-page: Custom login page url path.

default-target-url : url where the user should navigate after successful login.

authentication-failure-url: url where the user should navigate after a login failure.

username-parameter and password-parameter : username-parameter and password-parameter - These two are optional. By default spring-security accepts the parameter names “j_username” and “j_password” as username and password in the login form. If you want to given any other name to the username and password input fields in the login form, then you can specify the custom parameter names in these two attributes in tag.

Enable the Cross Site Request Forgery (CSRF) protection, refer to this link. In XML, by default, CSRF protection is disabled.

In “logout-success-url” you can specify the page url path which should execute when user uses spring-security logout process.


Step 5: Configuring LoginService in Spring Security XML:

Spring security have AuthenticationManager and it delegate to a collection of AuthenticationProvider instances.An AuthenticationProvider will call an object that implements the UserDetailsService interface. A UserDetailsService looks up the user data and returns a UserDetails object fully populated. If the UserDetailsService cannot find this user then a UsernameNotFoundException is thrown.UserDetailsService interface has just one method loadUserByUsername(String username) and  returns a UserDetails object, then the AuthenticationProvider will check that the password matches the password the user entered. If it does not match, then the AuthenticationProvider will throw an AuthenticationException.

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="loginService">
        </security:authentication-provider>
    </security:authentication-manager>



Below LoginService implemented from UserDetailsService and overriding method loadUserByUsername(String username).And referring loginService to authentication-provider in the XML configuration.And LoginService looks as


@Service("loginService")
public class LoginService implements UserDetailsService {

    @Autowired
    private HibernateTemplate hibernateTemplate;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
        User user = hibernateTemplate.get(User.class, username);
        if (user == null) {
            return null;
        }
        List<SimpleGrantedAuthority> simpleGrantedAuthorities = buildSimpleGrantedAuthorities(user);
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), user.getActive() == 1 ? true : false, true
                , true, true, simpleGrantedAuthorities);
        return userDetails;

    }

    private List<SimpleGrantedAuthority> buildSimpleGrantedAuthorities(final User user) {
        List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
        if (user.getRoles() != null) {
            for (Role role : user.getRoles()) {
                simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
            }
        }
        return simpleGrantedAuthorities;
    }
}

Step 6: Database Configuration

In the above Login service we autowired hibernate template to intract to database table.Below is the configuration to build Hibernate template
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/LoginDB"></property>
        <property name="username" value="root"></property>
        <property name="password" value="admin"></property>
        <property name="connectionProperties">
            <props>
                <prop key="hibernate.show_sql">
                    true
                </prop>
                <prop key="hibernate.enable_lazy_load_no_trans">
                    true
                </prop>
            </props>
        </property>
    </bean>

    <bean id="loginSessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.spring.security" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="loginSessionFactory"/>
    </bean>
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
        <property name="sessionFactory" ref="loginSessionFactory"/>
    </bean>

Step 7: Adding Controller

@Controller
public class HelloWorldController {

    @RequestMapping(value = {"/"}, method = RequestMethod.GET)
    public ModelAndView homePage() {
        ModelAndView model = new ModelAndView();
        model.addObject("greeting", "Hi, Welcome to hello world app. ");
        model.setViewName("welcome");
        return model;
    }

    @RequestMapping(value = {"/login"}, method = RequestMethod.GET)
    public ModelAndView loginPage() {
        ModelAndView model = new ModelAndView();
        model.addObject("greeting", "Hi, Welcome to login page");
        model.setViewName("login");
        return model;
    }

    @RequestMapping(value = {"/accessdenied"}, method = RequestMethod.GET)
    public ModelAndView accessDeniedPage() {
        ModelAndView model = new ModelAndView();
        model.addObject("message", "Either username or password is incorrect.");
        model.setViewName("accessdenied");
        return model;
    }

    @RequestMapping(value = {"/userpage"}, method = RequestMethod.GET)
    public ModelAndView userPage() {

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            Collection<? extends GrantedAuthority> authorities = ((UserDetails) principal).getAuthorities();
            if (authorities.size() == 1) {
                final Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
                GrantedAuthority grantedAuthority = iterator.next();
                if (grantedAuthority.getAuthority().equals("ADMIN")) {
                    return adminPage();
                }
            }
        }
        ModelAndView model = new ModelAndView();
        model.addObject("title", "Spring Security Hello World");
        model.addObject("user", getUser());
        model.setViewName("user");
        return model;
    }

    @RequestMapping(value = "/adminpage", method = RequestMethod.GET)
    public ModelAndView adminPage() {

        ModelAndView model = new ModelAndView();
        model.addObject("title", "Spring Security Hello World");
        model.addObject("user", getUser());
        model.setViewName("admin");
        return model;
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public ModelAndView logoutPage(HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        return homePage();
    }

    private String getUser() {
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            userName = ((UserDetails) principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }
}

Step 8: Adding Views  



1) welcome.jsp :
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld page</title>
</head>
<body>
    ${title}<br/><br/>
    Dear ${user}, you are successfully logged into this application.
    <br/>
    <a href="<c:url value="/logout" />">Logout</a>
</body>
</html>

2) login.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Login</title>
</head>
<body>
<h1>Spring Security Custom Login Form</h1>
 <div id="logindiv">
    <form name='loginForm' action="<c:url value='j_spring_security_check' />" method='POST'>
        <table>
         <tr>
       <td>User:</td>
       <td><input type='text' name='username' value=''></td>
      </tr>
      <tr>
       <td>Password:</td>
       <td><input type='password' name='password' /></td>
      </tr>
      <tr>
       <td colspan='2'><input name="submit" type="submit"
         value="submit" /></td>
      </tr>
     </table>
     <input type="hidden" name="${_csrf.parameterName}"
                 value="${_csrf.token}" />
    </form>
    </div>
</body>
</html>

3) user.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld page</title>
</head>
<body>
    ${title}<br/><br/>
    Dear ${user}, you are successfully logged into this application.
    <br/>
    <a href="<c:url value="/logout" />">Logout</a>
</body>
</html>

4) admin.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>HelloWorld page</title>
</head>
<body>
    ${title}<br/><br/>
    Dear ${user}, you are successfully logged into this application as admin.
    <br/>
    <a href="<c:url value="/logout" />">Logout</a>
</body>
</html>

5) AccessDenied.jsp :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Access Denied Page</title>
</head>
<body>
    <h2> Access Denied </h2>
    <br/>${message}<br/>

    Click here for<a href="<c:url value="/login" />"> Login</a>
</body>
</html>

Step 9 : Screens  


After deploying above application(spring-security-custom-login-using-hibernate.war) in web server(tomcat) and you can find below screens

1) welcome page :


2) Login page :


3) User Page :


4) Admin Page :


5) AccessDenied Page : 


Download Source : 

Please download source from GitHub.

Conclusion :

After reading this article you will get an idea how Spring Security works and how you can integrate spring security with database using hibernate with custom login form.