Home » Framework » Configure Spring Security in Spring Boot Application

Configure Spring Security in Spring Boot Application

Spring Boot Starter Security is used to secure the web application to prevent hacking. In this article, we are going to see how to configure the Spring Boot Starter Security in a fresh Spring Boot Application.

Before that, we should know some of the basic concepts of Spring Security. if you want to know more please take a look at Basic Concepts of Spring Boot Security.

Now let's see the configuration of spring boot starter security. First, we should create the project in Spring Initializr. Here are the steps below.

  1. Open the Spring Initializr website through this link https://start.spring.io/.
  2. Choose the Project as Maven and language like Java. Then Fill in the project metadata information like group, artifact, and project name, etc.
  3. Choose needed dependencies Spring Web, Spring Boot Actuator, and Spring Boot DevTools, and Spring Security.
  4. Click Generate button to generate the project.
Spring-Boot-Security-Initializr

That's it. We don't want to do any other configuration more. Spring Boot application takes care of everything. Now let's see why we added these dependencies in this project.

Spring Boot Starter Web - If we want to create any web application then we need this dependency as mandatory. This gives the REST API and MVC features to the application.

Spring Boot Actuator - It gives the production-ready features to the application like monitors the app, gathering metrics, understanding traffics, and so on.

Spring Boot Dev Tools - It is a developer tool. Developers use this tool to improve the development features in an application. It restarts the application every time when the changes are made and it has live reloaded features too.

Spring Boot Starter Security - If we want to secure the application then we need to use this dependency in the project. By default, this secures all the endpoints except the root path which means that it requires authentication to access the endpoints.

Now open the downloaded project in any IDE and test it. Here I used eclipse IDE to test the project. The entire project structure is below.

Spring-Boot-Starter-Security-Project-Structure

pom.xml file is 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.tipstocode</groupId>
	<artifactId>SpringBootSecurity</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringBootSecurity</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</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-security</artifactId>		    
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

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

</project>

For testing the application we have to create the Rest Controller with one endpoint. The controller code is below.

package com.tipstocode.SpringBootSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {	
	@GetMapping("/")
	public String helloWorld(){
		return "Welcome to the new world!";
	}
}

That's it. Now start the application. Once started then open this URL "http://localhost:8080/welcome" in any browser then it shows the login screen to ask for username and password.

Spring-Boot-Security-Login

By default the username is 'user' and the password is generated by the application itself and shown in the console. Just copy the password from the console and paste it here and submit the form. Then you will see the welcome message.

Spring-Boot-Security-Password

Actually when we try to access the endpoint "http://localhost:8080/welcome" in the browser then spring security shows the login screen to authenticate yourself first and shows the welcome message.

if you remove the "spring-boot-starter-security" in pom.xml and run the application again and test the same endpoint then it does not show the login screen to authenticate, it directly shows the welcome message.

Now you may have the question like how to override this default username and password with our own. Yes, we can do it. Spring security provides the option for that too.

You can put your own user name and password in the application.properties file like below then restart the application. Now you have to put your own username and password to authenticate the application.

spring.security.user.name=tipstocode
spring.security.user.password=password

If the application is configured with our own username and password in the application.properties file then you can not see the default password generated in the console.

Basic features added by Spring Security

Once we configured Spring Security with the application then these are all the features added by default to the spring boot application. The features are listed below.

  1. First, it secures all the URLs / Endpoints. If we try to access any endpoint then it should ask to authenticate first.
  2. It adds the login form to authenticate the users.
  3. It adds the logout features (We can log out the application using the URL "http://localhost:8080/logout")
  4. Handles the login validation and shows the error on the login screen.
  5. Created the default username as "user" and the default password is generated and shown in the console.

Configure more users in Spring Security

If you want to add more users to the application then we have to override the default authentication process of spring security and configure it to authenticate our own set of users.

Now let start to see how to do that.

By default, there is a manager called AuthenticationManger to authenticate the users through the authenticate() method. Actually, we can't create the new AuthenticationManager to authenticate our own set of users with our own logic.

Instead, we can create the AuthenticationManagerBuilder to look into that. AuthenticationMangerBulider handles what type of authentication it is and how to authenticate the users. This builder class overrides the default spring security authentication process.

For configuring this we have to extend the class called WebSecurityConfigurerAdapter and override the configure method which takes AuthenticationManagerBuilder as an argument. Within this function, we can define the authentication process. The configuration is like below.

package com.tipstocode.SpringBootSecurity;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception{		
		auth.inMemoryAuthentication()
		.withUser("user")
		.password("password")
		.roles("USER")
		.and()
		.withUser("admin")
		.password("password")
		.roles("USER");		
	}	
	@Bean
	public PasswordEncoder getPasswordEncoder(){
		return NoOpPasswordEncoder.getInstance();
	}
}

Actually, we have to fetch the user information from the database to authenticate. Here we are not dealing with database interaction so I have hard-coded some users in in-memory to tell the spring security to do the in-memory authentication.

Spring security does not deal with the clear text password but only it does authenticate with hashing password. So in a real-world application, the password should be encrypted using any of the hashing methods and stored.

But here for explaining easily I used a password encoder to return the clear text password with the help of the NoOpPasswordEncoder method. Actually, this method is deprecated now. So please do not use this in real applications.

Finally, the class is annotated with @EnableWebSecurity. That's it configuration is over. Now our application is ready to authenticate our own set of users.

Hope you understood how to configure spring boot security and how to override the default authentication and do the authentication with our own bunch of users. In the next article we will see how to configure the Authorization of Spring Boot Security. Keep Reading!..Thanks!...

Leave a Reply

Your email address will not be published. Required fields are marked *