Java and J2EE Tutorials, Jsp and Servlet Tutorials, Spring MVC, Solr, XML, JSON Examples, Hibernate & Struts 2 Hello World projects



Tuesday, 27 May 2014

Spring Security Custom Login Form Example

In our previous discussion we go through 'What is spring security' and 'Spring Security Example'. In this particular blog we will dive into how to set a custom login form in spring security application. Spring security provides an in-build login form if we does not provide a user defined form, but in real world applications we need to add spring security form login capabilities in our own designed login forms.


How to set custom login form in spring security

In this blog we will create a custom login form to make user enter their credential, those username and password will be that authenticated by spring security and required page will be displayed to the loggeedin user. We need to configure few attributes in spring-config file to make it possible to set custom login form, default landing page and logout functionality.


Project Structure

Let us first start with our maven project structure, and will go through all required configuration files one by one. See the rest part of this blog for detailed information on each step.



SpringSecurityCustomLogin\pom.xml

Here is a list of all required dependencies that we need to add in pom.xml, to get spring security basic features all we need to do is to add 'spring-security-web' and 'spring-security-config' to pm.xml file.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.beingjavaguys.sample</groupId>
 <artifactId>SpringSecurityCustomLogin</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>SpringSecurityCustomLogin Maven Webapp</name>
 <url>http://maven.apache.org</url>
 <properties>
  <spring.version>4.0.5.RELEASE</spring.version>
  <jdk.version>1.7</jdk.version>
  <context.path>SpringSecurityCustomLogin</context.path>
 </properties>
 <developers>

  <developer>
   <id>Nagesh Chauhan</id>
   <email>beingjavaguy@gmail.com</email>
   <organization>beingjavaguys.com</organization>
   <organizationUrl>http://www.beingjavaguys.com</organizationUrl>
   <roles>
    <role>Java Developer</role>
   </roles>
   <timezone>+5:30</timezone>
  </developer>
 </developers>

 <build>
  <finalName>${pom.artifactId}</finalName>

  <plugins>
   <!-- Maven compiler plugin -->
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>${jdk.version}</source>
     <target>${jdk.version}</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <dependencies>



  <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>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>

  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>3.2.4.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>3.2.4.RELEASE</version>
  </dependency>
 </dependencies>
</project>



\src\main\webapp\WEB-INF\web.xml

The very first thing we need to do is adding following filters to our web.xml. These filters tells the container that all upcoming requests will be handled by spring security for security purpose. DelegatingFilterProxy is a class present in spring-security jars which delegates control to a filter chaining defined in spring-security internals. Note that we have given the bean name as ‘springSecurityFilterChain’ one should not change the name of this bean as this is being configured by spring-security internal infrastructure. By adding these filters to web.xml now we are ready to configure security in the application.


 Sample Spring Maven Project

 
  mvc-dispatcher
  org.springframework.web.servlet.DispatcherServlet
  1
 

 
  mvc-dispatcher
  /
 

 
  org.springframework.web.context.ContextLoaderListener
 

 
  contextConfigLocation
  
   /WEB-INF/mvc-dispatcher-servlet.xml,
   /WEB-INF/security-config.xml
   
 

 
  springSecurityFilterChain
  org.springframework.web.filter.DelegatingFilterProxy
 

 
  springSecurityFilterChain
  /*
 



< br/>

\src\main\webapp\WEB-INF\mvc-dispatcher-servlet.xml

This is a simple spring configuration file with a view resolver bean to show jsp's and two useful annotation information regarding component-scan and annotation-driven.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

 <context:component-scan base-package="com.beingjavaguys.controller" />
 <mvc:annotation-driven />


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


</beans>

\src\main\webapp\WEB-INF\security-config.xml

By adding filter to web.xml we are now able to configure security in our application, we can start with minimal http configuration for incoming requests. This tells that all upcoming requests which are matching to the pattern given in ‘pattern’ attribute will be secured bu spring-security and these requests will need ‘ROLE_USER’ role to access them. Here the thing to be noted is that ‘ROLE_’ prefix is a marker to define roles, ‘access’ attribute can accept a number of roles separated by a comma. Regarding ‘’ we can have a number of different entries for different url’s, these entries will be evaluated in the order they are defined here. The very first match to the incoming request will be executed. We can also add a method attribute to limit the match to a particular HTTP method (GET, POST, PUT etc.).


 
  
  
  
 

 
  
   
    
   
  
 




\src\main\java\com\beingjavaguys\controller\LoginController.java

This is a simple Controller class with few request mappings in it, we have '/login' to redirect the user to login form along with custom messages if required. Another mapping id for profile page '/profile' only logged in users will be able to see 'profile' page.
package com.beingjavaguys.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

 @RequestMapping("login")
 public ModelAndView getLoginForm(
   @RequestParam(required = false) String authfailed, String logout) {
  String message = "";
  if (authfailed != null) {
   message = "Invalid username of password, try again !";
  } else if (logout != null) {
   message = "Logged Out successfully, login again to continue !";
  }
  return new ModelAndView("login", "message", message);
 }

 @RequestMapping("profile")
 public String geProfilePage() {
  return "profile";
 }

}


\src\main\webapp\WEB-INF\pages\login.jsp

This is actual custom login form that will be rendered to the user to add credentials and log in to the application. In this file all we need to do is adding spring specific action 'j_spring_security_check' so that spring-security can intercept it and can authentication done.
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Login Form | www.beingjavaguys.com</title>
</head>
<body>
 <center>
  <br /> <br /> <br />
  <h2>Login Here</h2>
  <br />
  <div
   style="text-align: center; padding: 30px; border: 1px solid green; width: 250px;">
   <form method="post"
    action="<c:url value='j_spring_security_check' />">

    <table>
     <tr>
      <td colspan="2" style="color: red">${message}</td>

     </tr>
     <tr>
      <td>User Name:</td>
      <td><input type="text" name="username" /></td>
     </tr>
     <tr>
      <td>Password:</td>
      <td><input type="password" name="password" /></td>
     </tr>
     <tr>
      <td> </td>
      <td><input type="submit" value="Login" /></td>

     </tr>
    </table>
   </form>
  </div>
 </center>
</body>
</html>

\src\main\webapp\WEB-INF\pages\profile.jsp

This is another simple jsp file, this will be rendered to the browser if the user is logged in successfully. We have also added a logout link in the page, logout functionality to work onw has to make the spring specific link '/j_spring_security_logout'. By clicking the link spring-security will logged out the current logged in used.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Profile Page | www.beingjavaguys.com</title>
</head>
<body>
<c:url value="/j_spring_security_logout" var="logoutUrl" />
 <center>
  <br /> <br /> <br />
  <h2>Profile Page | You are now logged in</h2>
  <h3><a href="${logoutUrl}">Logout</a></h3>
 </center>
</body>
</html>


Here we are done with all required configurations, if everything goes right you will see following screens in your browser. We have intercepted "/profile" url in 'spring-config'. Go to the browser and hit 'http://localhost:8080/SpringSecurityCustomLogin/profile'. We have intercepted '/profile' so spring-security will redirect the page to 'http://localhost:8080/SpringSecurityCustomLogin/login' and you will see following custom login screen.


Enter username as 'user' and password as 'user@123' and hit login, you will see the profile page as shown below.


Now hit 'logout' and you will be redirected to the login screen again showing a logged out success message.



In case you entered wrong username or password, you will be redirected to login form page along with wrong credential message as shown below.



This is all about setting custom login form in spring security. In upcoming blogs we will see more about Spring, Hibernate, Java and Other opensource technologies.








Thanks for reading !
Being Java Guys Team

Download "Spring Security Custom Login Form Example Project" from "SkyDrive"





0 comments:

Post a Comment

Like Us on Facebook


Like Us On Google+



Contact

Email: neel4soft@gmail.com
Skype: neel4soft