Spring Security 4 JAVA Config In Memory Authentication Authorize Requests Security Method

September 18, 2015 | 2354 views | Comments

Set up the combination of JAVA configuration, In Memory authentication, and Authorize Requests security method to develop a full Spring Security 4 authentication and authorization web application.

 

Built and tested with the following:

  • Eclipse Juno IDE
  • Apache Tomcat 7.0.47
  • JDK 1.7.0
  • Maven 3.0.4
  • Spring Web-MVC Framework 4.2.2
    • Configuration: XML
    • Url Mapping: Annotation
  • Spring Security 4.0.2
    • Configuration: JAVA
    • Authentication: In Memory
    • Security Method: Authorize Requests

 

Task: Integrate Spring Web-MVC Framework 4 with Spring Security 4 to create a "vendor-customer" user authentication and authorization system wherein each user has it's own private page with the exemption of allowing the vendor to have access on the customer page.


Summary

  • Step 1. Create a new Maven Project.
  • Step 2. Edit pom.xml file.
  • Step 3. Edit web.xml file.
  • Step 4. Create spring-servlet.xml file.
  • Step 5. Create the template files.
  • Step 6. Create the Security Config Classes.
  • Step 7. Create the Controller Class.

Step 1. Create a new Maven Project.

Enter the following details:

  • Group Id: com.consistentcoder
  • Artifact Id: spring-security-4-jc-inMemory-authorizeRequest
  • Name: spring security 4 jc inMemory authorizeRequest

Tutorials:
Create a New Maven Project in Eclipse
Configure Run on Server option on a Maven Project on Eclipse IDE

After you have followed the tutorials above, your Maven Project Structure would look something like below.

 

Step 2. Edit pom.xml file.

Have the following code inside it.

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.consistentcoder</groupId>
    <artifactId>spring-security-4-jc-inMemory-authorizeRequest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>spring security 4 jc inMemory authorizeRequest</name>
    
    <properties>
        <spring.version>4.2.2.RELEASE</spring.version>
        <springSecurity.version>4.0.2.RELEASE</springSecurity.version>
        <javaxServletApi.version>3.1.0</javaxServletApi.version>
    </properties>
  
    <dependencies>
        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
         <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${springSecurity.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${springSecurity.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${springSecurity.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${springSecurity.version}</version>
        </dependency>
        
        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javaxServletApi.version}</version>
        </dependency>
    </dependencies>
</project>

/pom.xml

 

Step 3. Edit web.xml file.

Replace current code with the following code.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>spring-security-4-jc-inMemory-authorizeRequest</display-name>
    
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

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

 

Step 4. Create spring-servlet.xml file.

Create a new XML file ("spring-servlet.xml") on the same folder where "web.xml" is located, and the contents are as follows.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:sec="http://www.springframework.org/schema/security"
	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-4.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <context:component-scan base-package="com.consistentcoder.controllers" />
    <mvc:annotation-driven />
    <mvc:resources mapping="/resources/**" location="/resources/" />
        
    <bean class="com.consistentcoder.config.SecurityConfig"/>
        
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/jsp/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>
</beans>

/src/main/webapp/WEB-INF/spring-servlet.xml

 

Step 5. Create the template files.

Step 5.1. Create the folder.

A "jsp" named folder should be created inside "WEB-INF" folder.

 

Step 5.2. Create the home page template file.

Create a new ".jsp" file ("index.jsp") inside "jsp" folder, and put the following code inside it.

<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome! - ConsistentCoder.com</title>
</head>
<body>
<h1>${ message }</h1>
<p>
    <a href="<%=request.getContextPath()%>/vendor">Vendor Page</a> | <a href="<%=request.getContextPath()%>/customer">Customer Page</a> | <a href="<%=request.getContextPath()%>/login">Login</a>
</p>
<p><u>Vendor login details</u></p>
<p>
    <ul>
        <li>username: <strong>vendor</strong></li>
        <li>password: <strong>vendor</strong></li>
    </ul>
</p>
<p><u>Customer login details</u></p>
<p>
    <ul>
        <li>username: <strong>customer</strong></li>
        <li>password: <strong>customer</strong></li>
    </ul>
</p>
</body>
</html>

/src/main/webapp/WEB-INF/jsp/index.jsp

 

Step 5.3. Create the customer page template file.

Inside folder "jsp", another folder should be created with the name "customer". Inside it, create a new ".jsp" file with the name "customer.jsp" and place the following code on it.

<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Customer Page - ConsistentCoder.com</title>
</head>
<body>
<h1>${ message }</h1>
<p>
    <form id="logout" action="<%=request.getContextPath()%>/logout" method="post" >
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
        <input type="submit" value="logout" />
    </form>
</p>
</body>
</html>

/src/main/webapp/WEB-INF/jsp/customer/customer.jsp

 

Step 5.4. Create the vendor page template file.

Create a new folder inside the folder "jsp", name it "vendor", and inside that folder, create a new ".jsp" file ("vendor.jsp"). Put the following code on it.

<%@ 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">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Vendor Page - ConsistentCoder.com</title>
</head>
<body>
<h1>${ message }</h1>
<p>You can also check the <a href="<%=request.getContextPath()%>/customer">Customer Page</a></p>
<p>
    <form id="logout" action="<%=request.getContextPath()%>/logout" method="post" >
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
        <input type="submit" value="logout" />
    </form>
</p>
</body>
</html>

/src/main/webapp/WEB-INF/jsp/vendor/vendor.jsp

 

The jsp template file structure should look similar with the image below.

 

Step 6. Create the Security Config Classes.

Create a new package and name it "com.consistentcoder.config". Inside that newly created package, two new JAVA Classes should be created, as listed below.

 

Step 6.1. Create MessageSecurityWebApplicationInitializer JAVA Class.

Tutorials:
Create a New Package on Eclipse IDE
Create a New JAVA Class on Eclipse IDE

package com.consistentcoder.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class MessageSecurityWebApplicationInitializer extends
        AbstractSecurityWebApplicationInitializer {
}

/src/main/java/com/consistentcoder/config/MessageSecurityWebApplicationInitializer.java

 

Step 6.2. Create SecurityConfig JAVA Class.

Tutorials:
Create a New Package on Eclipse IDE
Create a New JAVA Class on Eclipse IDE

package com.consistentcoder.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            //configure "In Memory" Authentication
            .inMemoryAuthentication()
            
            /*
             * configure user "vendor"
             * with password "vendor"
             * and role "ROLE_VENDOR"
             */
            .withUser("vendor").password("vendor").roles("VENDOR").and()
            
            /*
             * configure user "customer"
             * with password "customer"
             * and role "ROLE_CUSTOMER"
             */
            .withUser("customer").password("customer").roles("CUSTOMER")
            ;
    }
    
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            
                /*
                 * allow any user
                 * to access the main page,
                 * the login page,
                 * and the resources pages
                 */
                .antMatchers("/","/login","/resources/**").permitAll()
                
                /*
                 * require that any user
                 * who access vendor pages
                 * should have a role "ROLE_VENDOR"
                 */
                .antMatchers("/vendor/**").hasRole("VENDOR")
                
                /*
                 * configure that a user
                 * with either role "ROLE_CUSTOMER"
                 * or "ROLE_VENDOR"
                 * will have access
                 * to the customer pages
                 */
                .antMatchers("/customer/**").hasAnyRole("CUSTOMER, VENDOR")
            
                .and()
            
            /*
             * automatically generate 
             * the log in page 
             */
            .formLogin()
            ;
    }
}

/src/main/java/com/consistentcoder/config/SecurityConfig.java

Notes: Since Spring Security 4.0, "ROLE_" is automatically appended when configuring or checking roles, therefore:

.withUser("vendor").password("vendor").roles("VENDOR")
//.roles("VENDOR") automatically becomes .roles("ROLE_VENDOR")
.withUser("customer").password("customer").roles("CUSTOMER")
//.roles("CUSTOMER") automatically becomes .roles("ROLE_CUSTOMER")
.antMatchers("/vendor/**").hasRole("VENDOR")
//.hasRole("VENDOR") automatically becomrs .hasRole("ROLE_VENDOR")
.antMatchers("/customer/**").hasRole("CUSTOMER")
//.hasRole("CUSTOMER") automatically becomrs .hasRole("ROLE_CUSTOMER")

 

Step 7. Create the Controller Class.

Create another package and name it "com.consistentcoder.controllers". Inside that newly created package, create a new class with the name "Main".

package com.consistentcoder.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class Main {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String indexPage(ModelMap model) {

        model.addAttribute("message", "Hello Guest, this is the Home Page...");
        return "index";

    }
    
    @RequestMapping(value = "/vendor", method = RequestMethod.GET)
    public String vendorPage(ModelMap model) {

        model.addAttribute("message", "This is the Vendor Page....");
        return "vendor/vendor";
    }
    
    @RequestMapping(value = "/customer", method = RequestMethod.GET)
    public String customerPage(ModelMap model) {

        model.addAttribute("message", "This is the Customer Page....");
        return "customer/customer";
    }
}

/src/main/java/com/consistentcoder/controllers/Main.java

 

That's all!

Spring Security 4 JAVA Config with In Memory Authentication and Authorize Requests Security Method has been developed.

 

Final Project Structure

 

What's Next? Test the application.

Browse the following link after you had started your server. http://localhost:8080/spring-security-4-jc-inMemory-authorizeRequest/. "Home Page" will be displayed.

 

Clicking on the Customer Page and/or the "Vendor Page" will redirect the guest to the login page.

 

Login with Vendor details and visit the "Vendor Page".

 

Login with Vendor details and visit the "Customer Page".

 

Login with Customer details and visit the "Vendor Page".

 

Login with Customer details and visit the "Customer Page".

 

Login with Incorrect details.

 

"Logout".


References: