Clean β’ Professional
Security Testing ensures that your applicationβs endpoints are protected, accessible only to authorized users, and safe from common attacks.
In Spring Boot, security testing focuses on verifying authentication, authorization, and security configurations without relying on real users or external identity providers.
Security Testing is the process of verifying that an application is protected against unauthorized access, data leaks, and security vulnerabilities.
Its main goal is to ensure that only the right users can access the right resources, while keeping sensitive data safe.

In Spring Boot applications, security testing confirms that authentication, authorization, and access rules are correctly enforced.
Security testing helps you to:
Security testing typically verifies:
Spring Boot provides powerful tools for security testing through Spring Security Test support.
Commonly used tools include:
@WithMockUser β Simulates an authenticated user@WebMvcTest β Tests secured controllers onlyMockMvc β Sends mock HTTP requests@SpringBootTest β Runs full security integration testsThese tools allow you to test security rules without real authentication systems.
@WithMockUser?@WithMockUser is a Spring Security test annotation used to simulate an authenticated user during tests, without calling a real login API or authentication provider.
It allows you to test secured controllers and endpoints quickly and reliably.
In Short:Β
@WithMockUserlets you mock a logged-in user in Spring Boot security tests.
@WithMockUser?ROLE_ADMIN, ROLE_USER)@WithMockUser WorksDuring test execution, Spring Security:

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/admin")
public class AdminController {
@GetMapping("/dashboard")
@PreAuthorize("hasRole('ADMIN')")
public String dashboard() {
return "Admin Dashboard";
}
}
@RestController β Marks this class as a REST controller.@RequestMapping("/api/admin") β Base path for all endpoints in this controller.@GetMapping("/dashboard") β Handles GET requests to /api/admin/dashboard.@PreAuthorize("hasRole('ADMIN')") β Ensures only users with the ADMIN role can access this endpoint.
@WithMockUserimport org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
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.status;
@WebMvcTest(AdminController.class)
class AdminControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(username = "admin", roles = "ADMIN")
void shouldAllowAdminAccess() throws Exception {
mockMvc.perform(get("/api/admin/dashboard"))
.andExpect(status().isOk());
}
}
@WebMvcTest(AdminController.class) β Loads only the AdminController and Spring MVC infrastructure for faster tests.MockMvc β Simulates HTTP requests without starting a server.@WithMockUser β Mocks an authenticated user with the given username and roles.andExpect(status().isOk()) β Verifies that ADMIN users can access the endpoint.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.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.status;
@WebMvcTest(AdminController.class)
class AdminControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(username = "user", roles = "USER")
void shouldDenyUserAccess() throws Exception {
mockMvc.perform(get("/api/admin/dashboard"))
.andExpect(status().isForbidden());
}
}
@WithMockUser(username = "user", roles = "USER") β Mocks a non-admin user.status().isForbidden() β Confirms that access is blocked for users without the ADMIN role.@WithMockUserimport org.springframework.security.test.context.support.WithMockUser;
@WithMockUser(
username = "john",
roles = {"USER"},
authorities = {"READ_PRIVILEGES"}
)
What You Can Customize:
| Attribute | Description | Default |
|---|---|---|
username | Mock userβs name | "user" |
roles | Spring Security roles (prefixed with ROLE_) | USER |
authorities | Fine-grained permissions | None |
password | Mock user password | "password" |
value | Alias for username | "user" |
accountExpired, accountLocked, credentialsExpired, disabled | Account states to simulate blocked or inactive users | false |
@Test
@WithMockUser(
username = "john",
roles = {"USER"},
authorities = {"READ_PRIVILEGES"}
)
voidshouldAllowReadAccess()throws Exception {
mockMvc.perform(get("/api/resource/read"))
.andExpect(status().isOk());
}
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.security.test.context.support.WithAnonymousUser;
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.status;
@WebMvcTest(ProfileController.class)
class ProfileControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithAnonymousUser
void anonymousUserIsRejected() throws Exception {
mockMvc.perform(get("/api/profile"))
.andExpect(status().isUnauthorized());
}
}
@WithAnonymousUser β Simulates an unauthenticated user.status().isUnauthorized() β Verifies that anonymous access is blocked for secured endpoints.@WebMvcTest for controller-level security testing.Spring Security enables CSRF protection by default for state-changing HTTP methods (POST, PUT, DELETE).
These tests demonstrate how requests behave with and without a CSRF token.
CSRF Enabled (Default)
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.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void postWithoutCsrfShouldFail() throws Exception {
mockMvc.perform(post("/users"))
.andExpect(status().isForbidden());
}
}
status().isForbidden() confirms CSRF protection is working.Sending a Request With CSRF Token
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
@Test
void postWithCsrfShouldSucceed() throws Exception {
mockMvc.perform(post("/users").with(csrf()))
.andExpect(status().isOk());
}
.with(csrf()) adds a valid CSRF token to the request.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.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt;
import static org.springframework.security.core.authority.SimpleGrantedAuthority;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void jwtAuthenticatedRequest() throws Exception {
mockMvc.perform(get("/api/orders")
.with(jwt().authorities(new SimpleGrantedAuthority("ROLE_USER"))))
.andExpect(status().isOk());
}
}
jwt() β Mocks a JWT-authenticated request for testing without generating a real token.authorities(new SimpleGrantedAuthority("ROLE_USER")) β Grants roles or permissions to the mock JWT.@WebMvcTest.status().isOk() confirms the request successfully passes authentication and authorization.@Test
voidjwtUnauthorizedRequest()throws Exception {
mockMvc.perform(get("/api/orders")
.with(jwt().authorities(newSimpleGrantedAuthority("ROLE_GUEST"))))
.andExpect(status().isForbidden());
}
.jwt(jwt -> jwt.claim("sub", "user123")) to mock custom claims for testing.@WebMvcTest vs @SpringBootTest for Security| Annotation | Purpose | What It Loads | Performance | Best Use Case |
|---|---|---|---|---|
@WebMvcTest | Test controllers and security rules in isolation | Controllers and Spring Security configuration only; no database or service beans | Very fast | Role-based access, permission checks, and controller-level security |
@SpringBootTest | Full application security testing | Complete Spring context including filters, JWT/OAuth2, services, and database | Slower | End-to-end security validation including authentication, authorization, and integration with services |
@WithMockUser vs Real Authentication| Feature | @WithMockUser | Real Authentication |
|---|---|---|
| Purpose | Simulates a logged-in user for tests | Uses actual authentication mechanisms (JWT, OAuth2, username/password) |
| Setup | Simple annotation on test methods or classes | Requires full Spring Security config, user details, tokens, or login flow |
| Speed | Very fast | Slower due to real authentication and context setup |
| Use Case | Unit or controller-level security tests | End-to-end integration tests with real security |
| Control | Can easily customize username, roles, authorities, and account state | Must rely on actual database/users or token claims |
| Dependencies | No DB or external services required | Requires database or authentication provider setup |
| Accuracy | Mocks behavior; does not test real authentication flows | Fully tests authentication, token validation, and security filters |
@WithMockUserUse @WithMockUser for fast, isolated security testing:
@PreAuthorize, @RolesAllowed)Avoid it when testing real authentication flows:
For those scenarios, use a full Spring context:
@SpringBootTest
// with real security configuration and services
@WithMockUser for controller security tests@WebMvcTest@WithMockUser simulates authenticated usersSecurity Testing in Spring Boot ensures your APIs are safe, restricted, and correctly configured.
By using:
@WithMockUserMockMvc@WebMvcTest and @SpringBootTestyou can confidently verify authentication and authorization rules, prevent security bugs, and deliver secure, production-ready Spring Boot applications.