Testing Secured Endpoints
Assert that your access rules actually work - authenticated, anonymous, and wrong-role requests.
On this page
You wrote access rules in the Security module: public reads, LIBRARIAN-only writes, authenticated borrowing. But rules you don't test are rules you only hope work - and a single wrong matcher can leave an endpoint wide open. Spring Security Test lets you assert your rules for real: authenticated, anonymous, and wrong-role requests.
The test support
spring-security-test (included in the test starter) adds request post-processors and
annotations that put a fake authenticated user into a MockMvc request. The simplest is
@WithMockUser:
@WebMvcTest(BookController.class)
class BookSecurityTest {
@Autowired MockMvc mvc;
@MockitoBean BookService service;
@Test
void anonymousCannotCreateBooks() throws Exception {
mvc.perform(post("/api/books").contentType(APPLICATION_JSON).content("{}"))
.andExpect(status().isUnauthorized()); // 401 — no credentials
}
@Test
@WithMockUser(roles = "MEMBER")
void memberCannotCreateBooks() throws Exception {
mvc.perform(post("/api/books").contentType(APPLICATION_JSON).content(validBody))
.andExpect(status().isForbidden()); // 403 — wrong role
}
@Test
@WithMockUser(roles = "LIBRARIAN")
void librarianCanCreateBooks() throws Exception {
mvc.perform(post("/api/books").contentType(APPLICATION_JSON).content(validBody))
.andExpect(status().isCreated()); // 201 — allowed
}
}Three tests capture the whole rule for one endpoint: 401 when anonymous, 403 for the wrong role, 201 for the right one. If someone later fat-fingers the matcher, one of these turns red.
Test the negatives, not just the happy path
The dangerous bug isn't "the librarian can't create a book" - you'd notice that. It's "a member (or anonymous) can." Security tests earn their keep by asserting the requests that must be rejected. Always test the 401 and 403 cases, not only the success.
A security guard checking a building at night doesn't only confirm their own key opens the front door - they walk the halls and rattle every locked door to make sure it's actually locked. Testing only the allowed request is checking your own key works. The real job is rattling the doors that should be shut: the anonymous and wrong-role requests that must be turned away.
BookVault's rule: DELETE /api/books/{isbn} requires LIBRARIAN. Describe the three test
cases that fully cover this rule and the status each should assert - and say which of the
three is the one most likely to catch a genuine security regression.
Why is it essential to test the rejected (401/403) cases of a secured endpoint, not just the allowed one?
Key takeaways
- spring-security-test lets you put a fake authenticated user into MockMvc requests, e.g. with @WithMockUser(roles = ...).
- Cover each secured endpoint with three cases: anonymous (401), wrong role (403), and correct role (success).
- The valuable tests are the negatives - proving disallowed requests are actually rejected.
- A single wrong matcher can open an endpoint; security tests turn red when that happens.
- Test who is turned away, not only who is let in.