Spring Security Integration with Spring Boot
Last Updated :
30 Aug, 2024
Spring Security is a powerful and customizable authentication and access control framework for Java applications. It provides comprehensive security services for Java EE-based enterprise software applications. This article will integrate Spring Security with a Spring Boot application, covering configuration, authentication, and securing RESTful APIs.
Implementation of Spring Security in a Spring Boot Application
Below is the step-by-step implementation of Spring Security in a Spring Boot application.
Step 1: Add Dependencies
Add the necessary dependencies to your project for Spring Boot and Spring Security.
Maven:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
Gradle:
dependencies {
// Spring Boot Starter Web
implementation 'org.springframework.boot:spring-boot-starter-web'
// Spring Boot Starter Security
implementation 'org.springframework.boot:spring-boot-starter-security'
}
These dependencies include Spring Boot's web and security starters, which provide essential components for web applications and security features.
Step 2: Configure Spring Security
By default, Spring Security secures all endpoints and offers a simple authentication system. Create a configuration class to alter this.
Java
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.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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll() // Allow access to home and root
.anyRequest().authenticated() // All other requests need authentication
.and()
.formLogin()
.loginPage("/login") // Custom login page
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("password"))
.roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Use BCrypt for password encoding
}
}
Explanation:
- @EnableWebSecurity provides the Spring MVC integration and turns on web security capability for Spring Security.
- @Bean public PasswordEncoder passwordEncoder(), defines a PasswordEncoder bean that uses BCryptPasswordEncoder to encode and debug passwords. A reliable password hashing algorithm isbcryptt.
Step 3: Configure Authentication
Authentication protocols supported by Spring Security include JDBC, LDAP, OAuth2, and in-memory. WebSecurityConfigurerAdapter and overrides the configure(AuthenticationManagerBuilder auth) function to configure authentication.
Java
import org.springframework.context.annotation.Bean;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("regularUser")
.password(passwordEncoder().encode("userPass"))
.roles("USER")
.and()
.withUser("superAdmin")
.password(passwordEncoder().encode("adminPass"))
.roles("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Use BCrypt for password encoding
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Public endpoints accessible without authentication
.anyRequest().authenticated() // All other requests need authentication
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
Explanation:
- .antMatchers("/public/**").permitAll(), permits access to any URL beginning with "/public/" without authentication.
- @Bean public PasswordEncoder passwordEncoder(), Uses BCryptPasswordEncoder to define a PasswordEncoder bean. This is a popular option for safely hashing passwords.
Step 4: Secure RESTful APIs
Use the same configure(HttpSecurity HTTP) method to secure RESTful APIs, but adjust the authentication mechanism (e.g., JWT or OAuth2) accordingly.
Java
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class CustomSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // Disable CSRF for stateless APIs
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // Stateless session management
.and()
.authorizeRequests()
.antMatchers("/api/admin/**").hasAuthority("ROLE_ADMIN") // Restrict to ADMIN role
.antMatchers("/api/user/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN") // Allow USER and ADMIN roles
.antMatchers("/api/public/**").permitAll() // Public endpoints accessible to everyone
.anyRequest().authenticated() // Secure all other endpoints
.and()
.addFilterBefore(customJwtFilter(), UsernamePasswordAuthenticationFilter.class); // Add JWT filter
}
@Bean
public CustomJwtFilter customJwtFilter() {
return new CustomJwtFilter(); // Custom JWT filter for authentication
}
// Additional configuration for JWT or OAuth2 can be added here
}
Explanation:
- .csrf().disable(), Turns off the defense against Cross-Site Request Forgery (CSRF). This is common for stateless APIs, which do not require CSRF.
- .addFilterBefore(customJwtFilter(), Adds a customized JWT filter before the default UsernamePasswordAuthenticationFilter (, UsernamePasswordAuthenticationFilter.class). We'll handle JWT-based authentication with this filter.
Step 5: Make User Details Service
You must put UserDetailsService into practice for a more complex configuration, such as one that uses a database for authentication.
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository; // Assuming you have a UserRepository to fetch user data
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
}
}
Explanation:
- @Service identifies this class as a component of a Spring service. It means you may use dependency injection and component scanning in this class, which also offers business logic.
- @Autowired private UserRepository userRepository injects an instance of UserRepository. It is believed that database activities paboutuser data are handled by this repository.
Step 6: Testing Security Configuration
To make sure your security setup functions as intended, you must test it. The spring-security-test module from Spring Security offers assistance with testing.
Java
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@WebMvcTest
public class AuthenticationTests {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(username = "normalUser", roles = {"USER"})
public void testAccessToUserDashboardWithUserRole() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/home"))
.andExpect(status().isOk());
}
@Test
@WithMockUser(username = "normalUser", roles = {"USER"})
public void testAccessToAdminDashboardWithUserRole() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/admin/home"))
.andExpect(status().isForbidden());
}
}
Explanation:
- @SpringBootTest indicates that the class is a test for Spring Boot. For integration tests that need to have access to the application context, it launches the entire application backdrop.
- MockMvc allows you to test answers and mimic HTTP requests without having to launch an entire HTTP server.
Note: If you want to go through a sample authentication project implementation of Spring Security, then read this article: Authentication and Authorization in Spring Boot 3.0 with Spring Security
Conclusion
In conclusion, with Spring Security Integration into a Spring Boot application, you can manage authorization and authentication with a strong framework that will protect your application.
Similar Reads
How to Integrate Keycloak with Spring Boot and Spring Security?
Keycloak is Open Source Identity and Access Management (IAM) solution developed by Red Hat. By using this you can add authentication to applications and secure services with minimum effort. No need to deal with storing users or authenticating users. Keycloak provides user federation, strong authenti
2 min read
Properties with Spring and Spring Boot
Java-based applications using the Spring framework and its evolution into the Spring Boot and the properties play a crucial role in configuring the various aspects of the application. Properties can allow the developers to externalize the configuration settings from the code. Understanding how to wo
4 min read
Securing a Spring MVC Application with Spring Security
Securing web applications is crucial in today's world, where security threats are prevalent. Spring Security is a powerful, customizable authentication and access-control framework that is part of the larger Spring ecosystem. It helps secure Spring MVC applications by managing authentication, author
6 min read
Spring Boot Integration With MySQL as a Maven Project
Spring Boot is trending and it is an extension of the spring framework but it reduces the huge configuration settings that need to be set in a spring framework. In terms of dependencies, it reduces a lot and minimized the dependency add-ons. It extends maximum support to all RDBMS databases like MyS
4 min read
Spring Boot Security Auto-Configuration
Spring Boot Security Auto Configuration can simplify the process of securing the Spring Boot applications by providing default security configurations. It can automate the many common security tasks such as setting up the authentication, and authorization and it can handle the common security vulner
4 min read
Security with Spring Security and Spring Webflux
Spring WebFlux is a part of the Spring Framework that supports reactive programming, enabling non-blocking asynchronous request handling. When developing web applications with Spring WebFlux, securing the application is a crucial aspect to ensure unauthorized access is prevented. This article provid
3 min read
Spring Boot Setup with Kotlin
Spring Boot is one of the best frameworks available to build full-stack enterprise applications. Initially, Spring was used to build stand-alone applications on the Java Platform supporting easy-to-develop and providing lots of handy features to ease the application development. Why Kotlin is Used?T
5 min read
Spring Boot - Internationalization
Before understanding Spring Boot-Internationalization, we must know what internalization in general means. Internationalization is an action or process of making something international which means making things adaptable or available everywhere. In this article, we will be discussing Internationali
6 min read
Loading Initial Data with Spring Boot
Loading initial data into a Spring Boot application is a common requirement for seeding the database with predefined data. This data could include reference data, default settings, or simple records to populate the application upon startup. The main concept involves using Spring Boot's data initiali
3 min read
Spring Boot Integration With MongoDB as a Maven Project
MongoDB is a NoSQL database and it is getting used in software industries a lot because there is no strict schema like RDBMS that needs to be observed. It is a document-based model and less hassle in the structure of the collection. In this article let us see how it gets used with SpringBoot as a Ma
4 min read