In the previous chapter we have been seen that Spring Security provide the by default login form for authentication. But In this tutorial, we show you an example for spring security login form, how to create a custom login form and ask Spring Security to use it for login authentication.
Spring Security Concepts
Spring Security works around two core areas of security, Authentication and Authorization.
1. “Authentication“
It is the assurance that the user is actually the user he is claiming to be, for example, when the user logs into any application and gives his credentials, he authenticates himself. At the authentication level, spring supports various authentication models such as Http Basic authentication, Form Based authentication.
2. “Authorization“
It is the assurance that the user is allowed to access only those resources that he is authorized to use. For example, in a corporate application, there are some parts of an application where only admin have access and to some parts all the employees have access. These access rules are determined by the access rights given to each user of the system. At the authorization level, spring targets three main areas: authorizing web request, authorizing whether methods can be invoked and authorizing access to individual domain object instances.
Required Tools used for this Application:
- Spring MVC 3.0.1
- Spring Security 3.1.0
- STS 2.8.1.RELEASE
- Tomcat 7
- Jdk 1.7
Spring Security Login Form Based Example
To understand this application you have some prior knowledge about the Spring MVC web application.
Step 1: Please download the following more jars for Spring Security Lib from its official site.
To get started with the implementation, following jars need to be present in the class path of the project.
- spring-security-acl-3.1.3.RELEASE.jar
- spring-security-aspects-3.1.3.RELEASE.jar
- spring-security-cas-3.1.3.RELEASE.jar
- spring-security-config-3.1.3.RELEASE.jar
- spring-security-core-3.1.3.RELEASE.jar
- spring-security-crypto-3.1.3.RELEASE.jar
- spring-security-ldap-3.1.3.RELEASE.jar
- spring-security-openid-3.1.3.RELEASE.jar
- spring-security-remoting-3.1.3.RELEASE.jar
- spring-security-taglibs-3.1.3.RELEASE.jar
- spring-security-web-3.1.3.RELEASE.jar
Step 2: Create the project “SpringSecurityLoginFormExample” with packages“com.dineshonjava.security.controller” and create the “LoginSecurityController.java” file in this package.
Step 3: Some more folders also create on the “WEB-INF” folder with name libs, views for jars and jsp files respectively. Two files “sdnext-servlet.xml” and “sdnext-security.xml” are created on the “WEB-INF” folder.
Namespace Configuration:
The namespace configuration of the spring provides lot of shortcuts that hides much of the complexity of the framework. To start with this configuration, define a security filter in web.xml as shown below:
Step 4: Configuring web.xml for Spring Security
<web-app version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>sdnext</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>sdnext</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/sdnext-*.xml, </param-value></context-param> <welcome-file-list> <welcome-file>index</welcome-file> </welcome-file-list> <!-- 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> </web-app>
In the above configuration, DelegatingFilterProxy delegates the control to a filter implementation which is defined as a bean named springSecurityFilterChain. This bean is an infrastructure internal bean to handle namespace configurations. Once this configuration is done, all the incoming requests enter the spring framework for security checks.
Security Configuration:
The security configuration is done in XML file and can have any name such as sdnext-security.xml. This file needs to be loaded explicitly from web.xml. This is done by adding ContextLoadListener. The following lines needs to be added before security filter definition in web.xml.
Step 5: Spring Securing Configuration file (sdnext-security.xml)
<beans xmlns:p="http://www.springframework.org/schema/p" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <security:http auto-config="true"> <security:intercept-url pattern="/index*" access="ROLE_USER" /> <security:form-login login-page="/login" default-target-url="/index" authentication-failure-url="/fail2login" /> <security:logout logout-success-url="/logout" /> </bean></beans>
<security:user name=”dineshonjava” password=”sweety” authorities=”ROLE_USER” /> This configuration is done to enable form-login authentication model where the login page is login.jsp. Note that in the intercept tag, pattern for /index* is given and access rule is defined as ROLE_USER. That means /index* is redirect to /login to checked for security, which makes sense as login.jsp is the starting point from where the user is authenticated.
The tag <security:authentication-manager> processes the authentication information; <security:authentication-provider> defines the credential information and the roles given to each user (authentication information).
Step 6: Spring Configuration File (sdnext-servlet.xml)
<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:component-scan base-package="com.dineshonjava.security" /> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
Step 7: Creating LoginSecurityController class (LoginSecurityController.java)
package com.dineshonjava.security.controller; import java.security.Principal; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * @author Dinesh Rajput * */ @Controller public class LoginSecurityController { @RequestMapping(value="/index", method = RequestMethod.GET) public String executeSecurity(ModelMap model, Principal principal ) { String name = principal.getName(); model.addAttribute("author", name); model.addAttribute("message", "Welcome To Login Form Based Spring Security Example!!!"); return "welcome"; } @RequestMapping(value="/login", method = RequestMethod.GET) public String login(ModelMap model) { return "login"; } @RequestMapping(value="/fail2login", method = RequestMethod.GET) public String loginerror(ModelMap model) { model.addAttribute("error", "true"); return "login"; } @RequestMapping(value="/logout", method = RequestMethod.GET) public String logout(ModelMap model) { return "login"; } }
JSP Views-
In custom login form, you have to follow Spring Security standard name :
1. j_spring_security_check – Login service
2. j_spring_security_logout – Logout service
3. j_username – Username
4. j_password – Password
Step 8: Creating welcome page (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> <title>WELCOME TO SECURE AREA</title> </head> <body> Message : ${message} Author : ${author} <a href="https://www.blogger.com/%3Cc:url%20value=%22/j_spring_security_logout%22%20/%3E"> Logout</a> </body> </html>
login.jsp
<%@ 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"> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>Login Page For Security</title> <style> .errorblock { color: #ff0000; background-color: #ffEEEE; border: 3px solid #ff0000; padding: 8px; margin: 16px; } </style> </head> <body onload='document.f.j_username.focus();'> <h3>Login with Username and Password (Custom Login Page)</h3> <c:if test="${not empty error}"> <div class="errorblock"> Your login attempt was not successful, try again.<br /> Caused : ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message} </div> </c:if> <form name='f' action="<c:url value='j_spring_security_check' />" method='POST'> <table> <tr> <td>User:</td> <td><input type='text' name='j_username' value=''> </td> </tr> <tr> <td>Password:</td> <td><input type='password' name='j_password' /> </td> </tr> <tr> <td colspan='2'><input name="submit" type="submit" value="submit" /> </td> </tr> <tr> <td colspan='2'><input name="reset" type="reset" /> </td> </tr> </table> </form> </body> </html>
Step 9: Running the example
Export the example as war and deploy it Tomcat 7 server. While browsing the project you will get the following screen for loging:
Access URL “http://localhost:8080/sdnext/index“, Spring will redirect to your custom login form.
URL : http://localhost:8080/sdnext/login
If username/password is wrong, authentication failed, display custom error messages.
URL : http://localhost:8080/sdnext/fail2login
If username/password is correct, authentication success, display requested page.
URL : http://localhost:8080/sdnext/index
If username/password is correct, authentication success, display requested page.
on requested page click on Logout link.
URL : http://localhost:8080/sdnext/logout
Download Source Code + Libs
SpringSecurityLoginFormExample.zip
References
http://www.codeproject.com/Articles/253901/Getting-Started-Spring-Security
Spring Security
Spring Security documentation
- Spring Security Interview Questions and Answers
- Spring Security Java Based Configuration with Example
- Spring Security XML Namespace Configuration Example
- Spring Security XML Based Hello World Example
- Spring Security For Login Based Example Using Database
- Spring Security Authentication Example Using HTTP Basic
- Spring Security Authorized Access Control Example
- Spring Security Customized Access Denied Page
- Spring Security Custom Error Message
- Spring Security Logout Example
- Spring Security Fetch Logged in Username
- Spring Security Password Hashing
Hii Deenesh.it is showing this error.kindly help me
HTTP Status 404 –
——————————————————————————–
type Status report
message
description The requested resource () is not available.
and in console it is showing
Sep 29, 2013 4:39:23 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/SpringSecurityLoginFormExample/] in DispatcherServlet with name 'sdnext'
Hi Manoj,
Please update context root sdnext from SpringSecurityLoginFormExample in your application.
OR
call url using with /SpringSecurityLoginFormExample context URI.
example-
http://localhost:8080/SpringSecurityLoginFormExample/
Thanks,
Dinesh
Hii I tried evrything but it is still showing the 404 error—-
Nov 03, 2013 8:41:52 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/sdnext/] in DispatcherServlet with name 'sdnext'
Hii I tried evrything but it is still showing the 404 error—-
Nov 03, 2013 8:41:52 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/sdnext/] in DispatcherServlet with name 'sdnext'