5. Spring boot + Spring Security

We will use Spring boot with spring security as below –

Github Link:  Download

We can secure spring application using spring security API provided by spring –

Tools used for below project –

  1. Spring Boot 2.0.3.RELEASE
  2. Spring 5.0.7.RELEASE
  3. Tomcat Embed 8
  4. Maven 3.3
  5. Java 8
  6. Spring Tool Suite IDE (STS)

Step 1: Project Structure

 

 

 

 

 

 

 

 

 

 

Step 2: Create a project named SpringBootSpringSecurityDemo in STS (Refer Create new project in STS). Select web , security dependency from starter project  dependencies popup –

Step 3: Below pom.xml will be generated for you by STS . You need to add JSTL and Embeded tomcat dependency if it’s not present.

<?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>com.myjavablog</groupId>
<artifactId>SpringBootSpringSecurityDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SpringBootSpringSecurityDemo</name>
<description>Demo project for Spring Boot with spring security</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<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>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<!-- JSTL for JSP -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>

<!-- For JSP compilation -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.threeten/threetenbp -->
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>0.7.2</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

The spring-boot-starter-parent provides you all maven defaults required for any spring project.

Since we are developing a web application, we also need to add spring-boot-starter-web dependency. Additionally we need to include spring-boot-starter-security to provide security to this web application.
Let’s do security configuration first.

Conroller class- 

Step 4: Create “HelloController .java” file under com.myjavablog.controller package –

package com.myjavablog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
* @author anupb
*
*/

@Controller
public class HelloController {

@GetMapping("/hello")
public String getHomePage(Model model) {

model.addAttribute("message", "Lets make our app secure");

return "hello";

}

}

Its a simple controller with  only hello method inside it.

Below are the annotations used-

@Controller  –   @Controller is used to mark classes as Spring MVC Controller.

@GetMapping – This anootation is used map GET requests from browser to java methods.

If you run the application at this stage , spring boot will bootstrap spring security and default security will be provided. If you run the application and try to access http://localhost:8081/hello . This request will be intercepted by Spring security and will be redirected to login page as below –

 

 

 

 

 

Login with default username : user and password generated by spring in below logs –

 

 

 

 

 

 

Spring boot main file

Step 5: Create a  “SpringBootSpringSecurityDemoApplication.java”  file in package com.myjavablog

package com.myjavablog;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSpringSecurityDemoApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootSpringSecurityDemoApplication.class, args);
}
}

This is the main file which bootstraps spring application.

We have just added @SpringBootApplication and it does all the work.
Let’s understand more about this annotation.
@SpringBootApplication is an annotation that adds all of the following:

@Configuration – It makes the class as a source of bean definitions for the application context.
@EnableAutoConfiguration – It enables Spring boot to add beans presents in classpath setting and various property setting.
Normally you would add @EnableWebMvc for a Spring MVC application, 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 – It tells Spring to look for other components, configurations, and services in the default package, allowing it to find the controllers.
If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.

 

Step 6: Create a file named “WebSecurityConfiguaration.java” in package com.myjavablog

/**
*
*/
package com.myjavablog;

/**
* @author anupb
*
*/
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;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguaration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests().antMatchers("/hello*").access("hasRole('ROLE_ADMIN')").and().formLogin();

}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).
withUser("myjavablog").password("secure").roles("ADMIN");
}
}

@EnableWebSecurity – Enables security for our application.

http.authorizeRequests().antMatchers(“/hello*”) – Secures all the URLs containing hello word in it.

http.authorizeRequests().antMatchers(“/hello*”).access(“hasRole(‘ROLE_ADMIN’)”).and().formLogin() – Allows role based access to these URLs . User with only admin can access this URL.

auth.inMemoryAuthentication().withUser(“myjavablog”).password(“secure”).roles(“ADMIN”) – We are using in Memory authentication to authenticate the user. User credentials are stored in memory for this example. We can store them either in database , LDAP etc.

When user provides myjavablog/secure credentials in login form then only he can access URLs with /hello  as this user has ADMIN role.

Step 7: Now create application.properties file inside /src/main/resources folder.

spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
server.port=8081

This is simillar to dispatcher servlet in spring MVC to configure view resolution.

Step 8: Create index.jsp inside webapp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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=UTF-8">
<title>HelloWorld</title>
</head>
<body>
<a href="hello.html">Click here to read hello message </a>
</br>
<a href="<c:url value="/logout" />">Logout</a>
</body>
</html>

Step 9: Create hello.jsp inside webapp/WEB-INF/views

<%@ 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>Hello world Page</title>
</head>
<body>
${message}
</body>
</html>

Run the application

Step 10: Right Click on Project -> Debug As -> Maven Build

 

Step 8: Provide goals as below – 

mvn clean install spring-boot:run (Cmd prompt)

Or

 

Step 9:  Now go to URL http://localhost:8082/. Index page will open up as below –

 

 

 

 

 

 

 

Once you click on the link, this request will be intercepted by spring security and you will be asked to enter username and password.

 

 

 

 

 

 

 

 

 

Home page –

Bitnami