Spring Boot Security Configuration Testing

When building secure applications, it’s essential to ensure your Spring Security configuration behaves exactly as expected. Whether it’s custom login, role-based access, or JWT filters — testing these configurations is critical.

In this post, you’ll learn how to perform Testing for Spring Boot Security Configuration using JUnit 5, MockMvc, and @WithMockUser. We’ll walk through authentication, authorization, and common testing scenarios using com.kscodes.springboot package structure.

Spring Boot Security Configuration Testing

⚙️ Dependencies

Here’s what you need in your pom.xml:




    
    
        org.springframework.boot
        spring-boot-starter-security
    

    
        org.springframework.boot
        spring-boot-starter-web
    

    
    
        org.springframework.boot
        spring-boot-starter-test
        test
    

    
        org.springframework.security
        spring-security-test
        test
    


🛡️ Spring Security Configuration


package com.kscodes.springboot.config;

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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin()
            .and()
            .httpBasic();

        return http.build();
    }
}

📁 Sample Controller for Testing


package com.kscodes.springboot.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SampleController {

    @GetMapping("/admin/data")
    public String adminData() {
        return "Admin content";
    }

    @GetMapping("/user/data")
    public String userData() {
        return "User content";
    }

    @GetMapping("/public")
    public String publicData() {
        return "Public content";
    }
}

🧪 Security Configuration Test: Authentication & Authorization


package com.kscodes.springboot;

import com.kscodes.springboot.controller.SampleController;
import com.kscodes.springboot.config.SecurityConfig;
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.context.annotation.Import;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(controllers = SampleController.class)
@Import(SecurityConfig.class)
public class SecurityConfigurationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void accessWithoutAuthentication_shouldFail() throws Exception {
        mockMvc.perform(get("/admin/data"))
                .andExpect(status().isUnauthorized());
    }

    @Test
    @WithMockUser(username = "admin", roles = {"ADMIN"})
    void adminAccess_shouldSucceed() throws Exception {
        mockMvc.perform(get("/admin/data"))
                .andExpect(status().isOk())
                .andExpect(content().string("Admin content"));
    }

    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    void userAccess_toAdmin_shouldFail() throws Exception {
        mockMvc.perform(get("/admin/data"))
                .andExpect(status().isForbidden());
    }

    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    void userAccess_toUser_shouldSucceed() throws Exception {
        mockMvc.perform(get("/user/data"))
                .andExpect(status().isOk())
                .andExpect(content().string("User content"));
    }
}

🔄 Testing Login Scenarios

To test form login or basic authentication, you can simulate HTTP POST requests:


@Test
void testBasicAuth() throws Exception {
    mockMvc.perform(get("/user/data")
            .with(httpBasic("user", "password")))
            .andExpect(status().isUnauthorized()); // If no real user config
}

You’ll need an actual UserDetailsService for real login testing.

💡 Common Security Test Annotations

AnnotationDescription
@WithMockUserSimulates a logged-in user
httpBasic()Mocks HTTP Basic Auth
formLogin()Mocks form-based login
@WithUserDetailsLoads actual user details from DB (integration-style test)

✅ Best Practices for Spring Boot Security Configuration Testing

  • Always isolate controller testing with @WebMvcTest when verifying access rules.
  • Use @WithMockUser to simulate authenticated users in unit tests.
  • For integration-level security testing (real login), use @SpringBootTest.
  • Avoid exposing sensitive URLs in test logs or failing outputs.
  • If using JWT or OAuth2, consider SecurityMockMvcRequestPostProcessors.jwt().

📚 Summary

In this guide, we explored Testing for Spring Boot Security Configuration using:

  • MockMvc for request simulations
  • @WebMvcTest and @WithMockUser for unit-level security tests
  • HTTP status verification for role-based access
  • Best practices for writing effective, reliable tests

🔐 Spring Security Official Documentation


🧪 Spring Security Testing Module