Spring Security in MVC 4 Using Spring Boot
Spring Boot makes many Spring developers' lives easier. See how you can built a Spring MVC 4 application with Spring Security built in using Spring Boot to set it all up.
Join the DZone community and get the full member experience.
Join For FreeWell, after quite a long time, nearly a year, I am all set to publish my next post here. This has been a post that is long overdue and highly requested. I am going to write about how to secure a Spring MVC 4 web application using Spring Security. I am going to use Spring Boot to build a quick and configuration-less application. I have written in detail on how to use Spring Boot in a Spring Data Rest application here.
Spring Boot can be used with build tools such as Maven or Gradle. These build tools help you share jars between various applications, build your application and generate reports. I am going to use the same application that is provided in the spring security getting started guide but with JSP for views.
Set Up Project With Spring Boot
2. Click Next -> Check Create a simple project -> Give workspace location
4. Let us create a very simple spring mvc application and secure it using spring security. Rewrite your pom.xml file to match what is given below.
<?xml version="1.0" encoding="UTF-8"?>
<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>org.programmingfree</groupId>
<artifactId>pf-securing-web</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
-- If you notice in the above pom.xml we are adding two dependencies given below since we are using JSP for the views.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
-- Though we use "war" for packaging, we will still be able to execute it. This is taken care of by 'spring-boot-maven-plugin'.
-- We have 'spring-boot-starter-security' as one of the dependencies and this is going to bootstrap everything related to security for us.
5. Create views inside WEB-INF\jsp one by one.
src\main\webapp\WEB-INF\jsp\home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>Spring Security Example - ProgrammingFree</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a href="<spring:url value='/hello' />">here</a> to see a greeting.</p>
</body>
</html>
This is a simple welcome page and it is not going to be secured. This page has a link to a greeting page (hello.jsp) which can be accessed only after being authenticated.
src\main\webapp\WEB-INF\jsp\hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello <b><c:out value="${pageContext.request.remoteUser}"/></b> </h1>
<form action="/logout" method="post">
<input type="submit" value="Sign Out"/>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</body>
</html>
This page displays a greeting message with the name of logged in user and can only be accessed by autheticated users.
src\main\webapp\WEB-INF\jsp\login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<title>Spring Security Example </title>
</head>
<body>
<c:if test="${param.error ne null}">
<div>
Invalid username and password.
</div>
</c:if>
<c:if test="${param.logout ne null}">
<div>
You have been logged out.
</div>
</c:if>
<form action="/login" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
As the name states itself, this page contains the login form for the users to submit their credentials.
6. Create three java classes inside a package called 'hello' with the code given below.
src\main\java\hello\MvcConfig.java
package hello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
}
src\main\java\hello\WebSecurityConfig.java
package hello;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
src\main\java\hello\Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Throwable {
SpringApplication.run(Application.class, args);
}
}
That is all! Now to run the application, right click project, run as Maven Build with the goal, clean install spring-boot:run
This will install the project with all necessary dependencies, generate war file in target folder and start the embedded tomcat server provided by spring boot. Open a browser and hit http://localhost:8080/ to see the home page,
On clicking the link for greeting message, user will be redirected to login page as shown below,
If the credentials are wrong, user is redirected to login page with error message,

How it Works
First let me start with application setup. Throughout the implementation, we did not write any xml configuration and even web.xml is eliminated with the use of Spring Boot. Let me go step by step on how Spring Boot set up the application for us,
1. Once maven downloads all required libraries to the classpath (WEB-INF\lib), Spring Boot looks into the classpath and makes reasonable assumptions about what you’re missing, and adds it.
2. Spring Boot launches an application from a class which is annotated with @SpringBootApplication, so in our example it starts with 'Application.java'
@SpringBootApplication is a convenience annotation that adds all of the following:
-- @Configuration tags the class as a source of bean definitions for the application context.
-- @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.
-- Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.
-- @ComponentScan tells Spring to look for other components, configurations, and services inside the same package as it is in. In this case it looks in to all classes inside the 'hello' package.
Spring Security
Last we need to provide the user a way to display the current username and Sign Out. Update the hello.html to say hello to the current user and contain a "Sign Out" form as shown below
CSRF Attack
Published at DZone with permission of Priyadarshini Balachandran, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Understanding Data Compaction in 3 Minutes
-
Building a Flask Web Application With Docker: A Step-by-Step Guide
-
Decoding eBPF Observability: How eBPF Transforms Observability as We Know It
-
DevOps vs. DevSecOps: The Debate
Comments