Testing a secured endpoint
Make MockMvc run the real filter chain, then drive it with mock users, JWTs and CSRF tokens.
Open this lesson in the learning hubKey points
- A plain
standaloneSetupMockMvc has no security filters, so the test passes and proves nothing. - Boot applies
springSecurity()for you in@WebMvcTest. Build MockMvc by hand and you must call it yourself. @WithMockUser(roles = "ADMIN")puts an authenticated user in the context before the request runs.- A resource server needs a token, not a user: add
.with(jwt().authorities(...))from the test post-processors. - CSRF is on for cookie apps, so a POST needs
.with(csrf())or it fails with 403 for the wrong reason. - Assert the negative cases too. A happy-path-only test never notices a rule that quietly stopped working.
Example
@WebMvcTest(PostController.class)
class PostControllerSecurityTest {
@Autowired MockMvc mvc;
@Test
void anonymousIsRejected() throws Exception {
mvc.perform(post("/api/posts")).andExpect(status().isUnauthorized());
}
@Test
@WithMockUser(roles = "USER")
void plainUserIsForbidden() throws Exception {
mvc.perform(post("/api/posts").with(csrf()))
.andExpect(status().isForbidden());
}
@Test
void tokenWithTheRightScopeWins() throws Exception {
mvc.perform(post("/api/posts").with(csrf())
.with(jwt().authorities(new SimpleGrantedAuthority("SCOPE_post:write"))))
.andExpect(status().isCreated());
}
}
If a security test never fails, check the filters are even running.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Security course, and every lesson in it is listed on the Spring Security contents page.