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:
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.
Enter the following details:
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.
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
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
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
A "jsp" named folder should be created inside "WEB-INF" folder.
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
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
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.
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.
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
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")
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
Spring Security 4 JAVA Config with In Memory Authentication and Authorize Requests Security Method has been developed.
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".
Create a NodeJs Hello World example - https://t.co/7PS2IOu7bF
— Consistent Coder (@ConsistentCoder) Nobyembre 17, 2015