Spring Security for Spring MVC 4 Application Simple Example using Spring Boot
Well, 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 ...

Well, 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 for. I am gonna 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 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
When we are done implementing the project at the end of this tutorial, the project structure is going to look like this,
pom.xml
<?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); } }
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,
As you can see, the login page provides a simple form that captures a username and password and posts them to "/login". As configured, Spring Security provides a filter that intercepts that request and authenticates the user. If the user fails to authenticate, the page is redirected to "/login?error" and our page displays the appropriate error message. Upon successfully signing out, our application is sent to "/login?logout" and our page displays the appropriate success message.
User is redirected to login page after signing out, with a logout message,
If the credentials are wrong, user is redirected to login page with error message,
To know how to directly run the downloaded project, watch this video.
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
Keep yourself subscribed for getting programmingfree articles delivered directly to your inbox once in a month. Thanks for reading!
Thanks for sharing the useful tutorial..
ReplyDeleteSorry, but application doesn't work. After trying to access any page it writes:
ReplyDeleteWhitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Nov 16 14:57:45 CET 2015
There was an unexpected error (type=Not Found, status=404).
No message available
I got the same error
DeleteThank you for this tutorial, everything works )
ReplyDeleteAwesome Tutorial !!
ReplyDeleteHi there, but why CSS doesn't get loaded, please refer to the article how to use resources in spring boot security.
ReplyDeleteIt works without @EnableWebMVC how to make it use static resources with that annotation for security
DeleteAivivu vé máy bay giá rẻ
ReplyDeleteve may bay tet 2021
vé máy bay đi Mỹ bao nhiêu
vé máy bay đi Pháp
vé máy bay từ hồ chí minh đi hàn quốc
vé máy bay đi nhật bản bao nhiêu
mua vé máy bay đi Anh
Aivivu chuyên vé máy bay, tham khảo
ReplyDeletevé máy bay đi Mỹ
đặt vé máy bay từ mỹ về việt nam
vé bay từ nhật về việt nam
ve may bay tư duc ve viet nam
gia ve may bay vietjet tu han quoc ve viet nam
This comment has been removed by the author.
ReplyDeleteA person who recognizes clinical terms and also cognizant of all the medicines, tablets, shot liquids that remain in the pharmacy technician resume skills in their clinical terms in addition to even more layperson names.
ReplyDeleteđại lý Japan Airlines
ReplyDeletephí đổi vé máy bay China Airlines
điều kiện hoàn vé Eva Air
This article on Spring Security for Spring MVC 4 is incredibly informative, especially for developers looking to enhance their web applications' security. I believe integrating such security measures can be akin to managing a busy shop in papa's freezeria —efficiency and safety go hand in hand. The detailed approach really clarifies the complexities. Thanks for sharing this comprehensive guide!
ReplyDeleteNeed help with your HESI exam? hire someone to take my hesi exam and get expert assistance for top scores. Our professionals ensure a secure, confidential, and stress-free experience. Affordable and reliable exam help is available now—guarantee your success today!
ReplyDelete