Spring Boot Security Example
Hi Spring Boot fans. Today, we will follow how Nick added Spring Boot Security to his web application. We will see how Nick protects his resources by adding Spring Boot Security. Spring Security provides a wide-range of security services services for Java EE-based enterprise software applications. The two main areas of application security that Spring Security targets are “authentication and “authorization or access-control”.
1. Tools
2. Assumptions
Nick knows his way around Eclipse. He is familiar with Maven and has done a fair amount of coding in his lifetime. His project has been created using Eclipse Mars so all instructions are based on this IDE.
3. Project Object Model
The first thing he did was to add Spring Boot Security to the classpath.
pom.xml
<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.javacodegeeks.example</groupId> <artifactId>spring-boot-security</artifactId> <version>0.0.1-SNAPSHOT</version> ... <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ... </dependencies> ... </project>
The ellipses has been added for brevity. Web applications are secured by default if Spring Security is on the classpath. The basic features Nick got by default in his web application are:
- A
UserDetailService
bean with in-memory store. - Form-based login for the entire application. (authentication)
Spring Boot Security automatically secures all HTTP endpoints with HTTP Basic security. But it can be customized.
4. Endpoints
Nick’s app is based on Spring MVC. This is how he set up his view controllers to expose his templates.
ControllerConfig.java
package com.javacodegeeks.example; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class ControllerConfig implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/enigma").setViewName("enigma"); registry.addViewController("/login").setViewName("login"); } }
The above code shows the endpoints of Nick’s web app. He will be securing the /enigma endpoint because there are top secret messages in that endpoint. Only authorized personnel are allowed to access it. Nick ran the application (Run As -> Java Application) and accessed it on localhost. This is what he saw:
5. Secured Endpoint
To prevent unauthorized users from accessing the /enigma endpoint, Nick created the code below. The code below forces the user to sign in when hitting /enigma, otherwise, the said endpoint can be accessed by anybody.
MainSecurityConfig.java
package com.javacodegeeks.example; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @Configuration @EnableWebSecurity public class MainSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/js/**", "/css/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Bean @Override public UserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("007") .password("JamesBond") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } }
The above code is the meat of Nick’s web security. His class is annotated with @EnableWebSecurity
to enable Spring Boot Security’s web security support and provide the Spring MVC integration. He also extended WebSecurityConfigurerAdapter
and has overriden some of its methods to customize the web security configuration.
The configure
method defines which URL paths are secured and which are not. The above code secures the /enigma endpoint as it was his task was to do so. All other paths do not need any authentication.
Nick provided a custom login page as specified by .loginPage("/login")
. Recall that this was mapped in ControllerConfig.java
. So users accessing /engima will have to login before they are able to view the web page.
The userDetailsService
method sets up an in-memory user store with a single user. The username is 007 and the password is JamesBond with a role of “USER” (authorization or access-control). The method withDefaultPasswordEncoder
is unsafe for production use because the password is compiled into the source code and is then included in memory at the time of creation. Which means it can be recovered as a plain text password making it unsafe. Nick is using it because this is just a fantasy example. For production purposes, ensure the password is encoded externally.
Below is how the login screen looks like.
6. Authenticated Access
If the user supplied the correct username and password, he shall see the top secret message as shown below.
7. Spring Boot Security Summary
Let’s summarize what Nick did in order to add Spring Boot Security to his web app. To secure his web app, he added Spring Boot Security to the classpath. Once it was in the classpath, Spring Boot Security was enabled by default. He then customized the security by extending WebSecurityConfigurerAdapter
and added his own configure
and userDetailsService
implementation. That’s all there is to it and Nick is a happy camper.
8. Download the Source Code
This is an example about Spring Boot Security.
You can download the source code of this example here: spring-boot-security.zip